Как вырезать строку из строки

Мой скрипт получает эту строку, например:

/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file

скажем, я не знаю, как долго строка до /importance,

Я хочу новую переменную, которая будет хранить только /importance/lib1/lib2/lib3/file из полной строки.

Я пытался использовать sed 's/.*importance//' но это дает мне путь без importance....

Вот команда в моем коде:

find <main_path> -name file | sed 's/.*importance//

Я не знаком с регулярным выражением, поэтому мне нужна ваша помощь, пожалуйста:)

Извините, друзья, я просто ошибаюсь по поводу моего вопроса, мне не нужен вывод /importance/lib1/lib2/lib3/file но /importance/lib1/lib2/lib3 без / файл в выводе.

Вы можете мне помочь?

6 ответов

Решение

Я хотел бы использовать awk:

$ echo "/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file" | awk -F"/importance/" '{print FS$2}'
importance/lib1/lib2/lib3/file

Который так же, как:

$ awk -F"/importance/" '{print FS$2}' <<< "/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file"
importance/lib1/lib2/lib3/file

То есть мы устанавливаем разделитель полей на /importance/, так что первое поле - это то, что предшествует ему, а второе - то, что идет после. Печатать /importance/ сам мы используем FS!

Все вместе и чтобы сохранить его в переменной, используйте:

var=$(find <main_path> -name file | awk -F"/importance/" '{print FS$2}')

Обновить

Мне не нужен вывод /importance/lib1/lib2/lib3/file но /importance/lib1/lib2/lib3 без / файл в выводе.

Тогда вы можете использовать что-то вроде dirname чтобы получить путь без самого имени:

$ dirname $(awk -F"/importance/" '{print FS$2}' <<< "/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file")
/importance/lib1/lib2/lib3

чистый удар

kent$ a="/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file"

kent$ echo ${a/*\/importance/\/importance}   
/importance/lib1/lib2/lib3/file

внешний инструмент: grep

kent$ grep -o '/importance/.*' <<<$a    
/importance/lib1/lib2/lib3/file

С GNU sed:

echo '/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file' | sed -E 's#.*(/importance.*)#\1#'

Выход:

/ Значение /lib1/lib2/lib3/ файл

Вместо того, чтобы заменять все до важности ничем, замените на /importance:

~$ echo $var
/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file
~$ sed 's:.*importance:/importance:' <<< $var
/importance/lib1/lib2/lib3/file

Как отмечает @lurker, если importance может быть в некоторых dirВы можете добавить /Чтобы быть в безопасности:

~$ sed 's:.*/importance/:/importance/:' <<< "/dir1/dirimportance/importancedir/..../importance/lib1/lib2/lib3/file"
/importance/lib1/lib2/lib3/file

Я пытался использовать sed 's/.*importance//' но это дает мне путь без importance....

Вы были очень близки Все, что вам нужно было сделать, это заменить обратно importance:

sed 's/.*importance/importance/'

Тем не менее, я бы использовал встроенное в Bash расширение шаблона. Это гораздо эффективнее и быстрее.

Расширение шаблона ${foo##pattern} говорит взять переменную оболочки ${foo} и удалите самый большой соответствующий шаблон глобуса с левой стороны переменной оболочки:

file_name="/dir1/dir2/dir3.../importance/lib1/lib2/lib3/file"
file_name=${file_name##*importance}

Удаление /file в конце, как вы спрашиваете:

echo '<path>' | sed -r 's#.*(/importance.*)/[^/]*#\1#'
  • вход /dir1/dir2/dir3.../importance/lib1/lib2/lib3/file
  • Возвращает: /importance/lib1/lib2/lib3

Смотрите этот учебник " Группы совпадений".

Другие вопросы по тегам