Как вырезать строку из строки
Мой скрипт получает эту строку, например:
/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
Смотрите этот учебник " Группы совпадений".