grep и избегая знака доллара

31

Я хочу знать, какие файлы имеют строку $Id$.

grep \$Id\$  my_dir/mylist_of_files

возвращает 0 вхождений.

Я обнаружил, что я должен использовать

grep \$Id$ my_dir/mylist_of_files

Затем я вижу, что $Idцвет на выходе, то есть он был сопоставлен.

Как я могу соответствовать второй $и почему не \$Id\$работает.

Не имеет значения, является ли второй $символ последним или нет.

Я пользуюсь grep2.9.


Прежде чем опубликовать свой вопрос, я использовал Google ...

Я нашел ответ

Чтобы найти $ (знак доллара) в файле с именем test2, введите:

grep \\ $ test2

Символы \\ (двойная обратная косая черта) необходимы для того, чтобы заставить оболочку передать команду \ $ (одиночная обратная косая черта, знак доллара) команде grep. Символ \ (одиночная обратная косая черта) указывает команде grep обрабатывать следующий символ (в данном примере $) как буквенный символ, а не как символ выражения. Используйте команду fgrep, чтобы избежать необходимости использования escape-символов, таких как обратный слеш.

но я не понимаю, почему grep \$Idработает, а почему grep \\$Id\\$нет.

Я немного смущен ...

Люк М
источник

Ответы:

25

Здесь есть 2 отдельных вопроса.

  1. grepиспользует базовые регулярные выражения (BRE) и $является специальным символом в BRE только в конце выражения. Следствием этого является то, что 2 экземпляра $in $Id$не равны. Первый является нормальным символом, а второй - якорем, соответствующим концу строки. Для того, чтобы сделать второй $матч в буквальном смысле $вам придется обратный слэш избежать его, то есть $Id\$. Экранирование первого $также работает: \$Id\$и я предпочитаю это, так как оно выглядит более последовательным.

  2. Здесь работают два совершенно не связанных между собой механизма экранирования / цитирования: цитирование в оболочке и обратная косая черта в регулярных выражениях. Проблема в том, что многие символы, которые используют регулярные выражения, также являются специальными для оболочки, и, кроме того, escape-символ regex, обратная косая черта, также является символом цитирования оболочки. Вот почему вы часто видите путаницы с двойной обратной косой чертой, но я не рекомендую использовать обратную косую черту для цитирования регулярных выражений оболочки, потому что она не очень читаема.

    Вместо этого, самый простой способ сделать это - сначала поместить все регулярное выражение в одинарные кавычки, как в 'regex'. Одиночная кавычка является самой сильной формой цитирования, которую имеет оболочка, поэтому, пока ваше регулярное выражение не содержит одинарных кавычек, вам больше не нужно беспокоиться о цитировании оболочки и можете сосредоточиться на чистом синтаксисе BRE.

Итак, применив это обратно к исходному примеру, давайте бросим правильный regex ( \$Id\$) внутри одинарных кавычек. Следующее должно делать то, что вы хотите:

grep '\$Id\$' my_dir/my_file

Причина \$Id\$не работает потому , что после удаления оболочки цитаты (более правильный способа сказать оболочки квотирования) применяются регулярное выражение , что grepвидит $Id$. Как объяснено в (1.), это регулярное выражение соответствует литералу $Idтолько в конце строки, потому что первый $является литералом, а второй - специальным якорным символом.

¹ Обратите также внимание, что если вы когда-либо переключаетесь на расширенные регулярные выражения (ERE), например, если вы решили использовать egrep(или grep -E), $символ всегда будет особенным. В ERE $Id$никогда не будет ничего совпадать, потому что у вас не может быть символов после конца строки, поэтому \$Id\$это будет единственный путь.

jw013
источник
3
Чтобы избежать интерпретации grep 1-го параметра как регулярного выражения, вы также можете это сделать grep -F '$Id$'.
jfg956
У меня в оболочке (bash 4.3.42) grep '$Id\$' ...и grep \$Id\\$ ...работа
ницас
2
И если это команда в Makefile, вы должны также спасаясь от $с предшествующим $: grep '$$Id\$$'. stackoverflow.com/a/2382810/2097284
Камиль Гудесюн
-2

Для поиска $Id$в файле: вы можете использовать:grep '\$id*' filename

Bala
источник
2
Это будет соответствовать всему, начиная с $id, $ideaнапример, не только $id$.
Terdon