Почему grep не возвращает то, что я ожидаю, когда я использую одинарные кавычки

У меня есть файл с содержимым ниже:

sh-4.2$ cat file1 example of multiple pattern this is an example of multipole sorry multiple pattern matching using grep so the example is the file itself -example -multiple -bye tata ! 

При поиске «-пример» в вышеуказанном файле команда grep не дает желаемого результата. Я знаю, если шаблон содержит «-», то следует использовать опцию -e:

В первом примере я использовал -example напрямую без кавычек:

 sh-4.2$ grep -example file1 example of multiple example of multipole so the example is the -example 

Например, одинарные кавычки:

 sh-4.2$ grep '-example' file1 example of multiple example of multipole so the example is the -example 

-пример с двойными кавычками и escape-символами

 sh-4.2$ grep "\-example" file1 -example sh-4.2$ 

3 Solutions collect form web for “Почему grep не возвращает то, что я ожидаю, когда я использую одинарные кавычки”

Ну, вы знаете, что шаблон поиска содержит «-», и вы знаете, что, когда шаблон поиска содержит «-», вам нужно использовать флаг -e . Поскольку вы не используете флаг -e оболочка интерпретирует ваш «шаблон» как аргумент (и параметр). Вы можете видеть это с помощью:

 $ grep "-foo" file1 grep: oo: No such file or directory 

По расширению ваш код grep "-example" file1 сообщает оболочке, что вы хотите запустить grep с аргументом -e и параметром «xample».

Это та же проблема, с которой мы сталкиваемся, когда пытаемся что-то вроде rm -my-silly-file-name – это не сработает, и нам нужно использовать что-то вроде rm ./-my-silly-file-name . Другим обходным решением будет rm -- -my-silly-file-name . Мы можем использовать эту идиому здесь:

 $ grep -- "-example" < file1 -example 

«-» сообщает оболочке, что все после нее не является аргументом.

Кроме того, вы можете просто избежать «-» с помощью «\», как вы видели:

 grep "\-example" file1 

В этой статье приводятся некоторые сведения о цитировании : соответствующая часть – это команды Parameters и backquoted, которые должны интерпретироваться оболочкой, заключены в двойные кавычки. Когда вы используете двойные кавычки, содержимое интерпретируется оболочкой.

Вы «знаете, если шаблон [начинается с]« – », тогда следует использовать опцию« -e », но вы не используете его, когда хотите. grep -e -example file1 даст вам ожидаемый результат.

Вот что на самом деле выполняется в каждом из ваших примеров:

  • grep -example file1 => grep -e xample file1 (-e необходимо)
  • grep '-example' file1 => grep -e xample file1 (-e необходимо)
  • grep "\-example" file1 => grep \-example file1 (-e не требуется)

Аргумент, который начинается с - принимается как опция.

В ваших первых двух случаях первый аргумент, переданный grep является -example , который grep понимает как -e xample (аргумент xample для опции -e , поэтому ищите xample ).

В третьем случае \-example передается в grep . Поскольку это не начинается с - , это не считается вариантом. Вместо этого он используется как регулярное выражение. Однако поведение для \- не указано в соответствии с POSIX, поэтому у вас нет никакой гарантии относительно того, что он соответствует. С большинством реализаций grep , \- будет соответствовать a - , однако вы можете представить реализации grep где \- может быть специальным оператором (см., Например, GNU grep где \+ – специальный оператор и не соответствует литералу + ).

Если вы хотите – -example чтобы не быть -example в качестве опции, вам необходимо:

  • grep -- -example file . Значок -- обозначает конец опций. Все, что после него не является опцией (так что первый аргумент шаблона для поиска, а остальное – список файлов для просмотра).
  • grep -e -example file . Здесь -example принимается за аргумент опции -e .

Вот почему вы должны привыкнуть писать:

 grep -e "$pattern" file 

Или

 grep -- "$pattern" file 

если вы не можете гарантировать, что $pattern не начнется с.

Обратите внимание, что здесь вы также можете написать:

 grep '[-]example' file 

Хотя см. Выражение скобки (без диапазонов), сопоставляющее неожиданный характер в bash о возможных осложнениях с этим подходом.

  • Исключение нескольких шаблонов с помощью одной команды grep
  • Извлечение частей текста с помощью sed, awk
  • Подавлять сообщения об усечении файла при использовании хвоста
  • Греп для слова в двух перевернутых запятых
  • Ошибка grep: операнд оператора повторения недействителен
  • Диапазон значений grep (/ sed / awk)
  • регулярные выражения с grep
  • Как получить путь, индекс строки и содержимое строки в оболочке bash?
  • Найти и удалить много файлов по определенному контенту
  • Bash для эхо-первого позиционирования каждой строки в файл с именем второго
  • BC возвращает синтаксическую ошибку
  • Linux и Unix - лучшая ОС в мире.