Начну с того, что считаю эту проблему чуть менее невинной, чем кажется.
Что мне нужно сделать: проверить папку в переменной окружения PATH. Это может быть в начале или где-то после. Мне просто нужно убедиться, что эта папка есть.
Пример моей проблемы - давайте использовать /opt/gnome
.
СЦЕНАРИЙ 1: папка не находится в начале пути
# echo "$PATH"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
# echo "$PATH" | grep ":/opt/gnome"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
Обратите внимание, что grep должен быть достаточно конкретным, чтобы он не зацепился /var/opt/gnome
. Отсюда и двоеточие.
СЦЕНАРИЙ 2: папка находится в начале ПУТИ.
# echo "$PATH"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
# echo "$PATH" | grep "^/opt/gnome"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
Это моя проблема - мне нужно искать двоеточие или начало строки с этой папкой. Я хотел бы сделать одно из следующих двух выражений:
# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"
НО [^
и [:
имеют свои значения. Таким образом, две команды выше не работают.
Есть ли способ я могу grep для этих двух сценариев в одной команде?
источник
/opt/gnome:
или/opt/gnome$
, вы найдете/opt/gnome-foo
или/opt/gnome/bar
.grep '^\(any number of other matches:*:\)*my match\(:.*\)*$'
Ответы:
Если вы проверяете содержимое
PATH
переменной среды, а не ищете что-то в файле, тогдаgrep
это неправильный инструмент. Это проще (и быстрее, и, возможно, более читабельно) сделать это в оболочке.В bash, ksh и zsh:
Портабельно:
Обратите внимание на использование,
:$PATH:
а не$PATH
; таким образом, компонент всегда окружен двоеточиями в строке поиска, даже если это было в начале или в конце$PATH
.Если вы ищете строку файла, вы можете использовать расширенное регулярное выражение (т.е. требующее
grep -E
)(^|:)/opt/gnome($|:)
для сопоставления,/opt/gnome
но только если оно находится либо в начале строки, либо после двоеточия, и только если оно либо в конце линия или после двоеточия.источник
Вы можете использовать расширенные регулярные выражения, просто используя
grep -E
Вы должны соответствовать началу и концу пути, который вы пытаетесь найти, если хотите избежать ложных срабатываний.
Соответствует экземпляру в начале:
Также соответствует экземпляру в середине:
Как избежать ложных срабатываний:
Там нет совпадений.
Компактный и элегантный. Протестировано на Debian 7.
источник
egrep
является устаревшим использованиеgrep -E
(источник:man grep
)-w
опции есть некоторые проблемы. Только цифры, буквы и подчеркивание считаются «словами». Так что некоторые необычные, но возможные символы заставят его потерпеть неудачу. Примерecho '/sbin:/usr/sbin:/var-/opt/gnome' | grep -w "/opt/gnome"
аecho '/sbin:/usr/sbin:/var./opt/gnome' | grep -w "/opt/gnome"
. Те дают неправильные результаты./opt/gnome/somethingelse
.echo "/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta" | grep -E "(:|^)/opt/gnome(:|$)"
. Редактирование ответа.Если вы не замужем
grep
, вы можете использоватьawk
и отделить записи на:
источник
Вы также можете использовать
echo "$PATH" | tr ':' '\n' | grep -x "/opt/gnome"
которая разбивает переменную пути на отдельные строки (по одной на путь), поэтому
grep -x
можно искать точные результаты. Это, конечно, имеет тот недостаток, что требует дополнительного процессаtr
. И это не будет работать, когда имя папкиPATH
содержит символы новой строки.источник
Я не знаю, достаточно ли этого для ответа, но
удовлетворит вашу потребность.
но
источник
/
это не часть слова, аr
есть./opt/gnome-beta
,/home/bob/opt/gnome
, ...grep -w /usr/local -o <<< /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
------/usr/local /usr/local /usr/local
Чтобы выделить
/opt/gnome
окружение, не содержащее слов (новые строки:
,/
и т. Д.), Попробуйте следующее:источник
Вы можете сделать это надежно и без особых усилий
grep
. Вы можете воспользоваться преимуществами расширений, которые широко доступны и среди которых уже было предложено много решений, но даже с базовым регулярным выражением это легко сделать, хотя на первый взгляд это не так интуитивно.С базовым регулярным выражением - и так далее
grep
- у вас всегда есть два надежных якоря - голова и хвост линии. Вы можете привязать совпадение к обоим из них независимо от их местоположения в строке, например:grep
будет сопоставлять от начала строки столько вхождений\(grouped\)
подвыражений, сколько должно встретить следующий ваш разделитель, затем ваше явное совпадение, и от хвоста вашего совпадения до конца строки таким же образом. Если ваше явное соответствие не совпадает явно оно завершится ошибкой и ничего не напечатает.И так вы могли бы сделать, например:
Посмотреть на себя:
ВЫВОД
источник
вы заметили крайний случай ... вы могли бы избежать этого, вызвав появление: в начале строки:
или, если путь точный, добавьте также один в конце, чтобы убедиться, что он ограничен:
источник