У меня есть файл с "тогда" и "там".
Я могу
$ grep "then " x.x
x and then some
x and then some
x and then some
x and then some
и я могу
$ grep "there " x.x
If there is no blob none some will be created
Как я могу найти оба в одной операции? Я пытался
$ grep (then|there) x.x
-bash: синтаксическая ошибка рядом с неожиданным токеном `('
а также
grep "(then|there)" x.x
durrantm.../code
# (Nothing)
grep
regular-expression
Майкл Даррант
источник
источник
Ответы:
Вы должны поставить выражение в кавычки. Ошибка, которую вы получаете, является результатом интерпретации bash
(
как специального символа.Также вам нужно указать grep использовать расширенные регулярные выражения.
Без расширенных регулярных выражений, придется бежать
|
,(
и)
. Обратите внимание, что здесь мы используем одинарные кавычки. Bash специально обрабатывает обратную косую черту в двойных кавычках.Группировка не нужна в этом случае.
Это было бы необходимо для чего-то вроде этого:
источник
grep $'then\nthere'
иgrep -e then -e there
. Обратите внимание, что\|
это не является стандартным в BRE. Остальное есть. Bash обрабатывает обратные косые специально в двойных кавычках только до"
,$
,\
,`
и символ новой строки.x.x
?Просто быстрое дополнение, большинство разновидностей имеют команду egrep, которая просто grep с -E. Мне лично нравится гораздо лучше печатать
Чем использовать grep -E
источник
Материал, задокументированный в разделе РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ на (или, по крайней мере, моей) справочной странице, на самом деле предназначен для расширенных регулярных выражений;
Но grep не использует их по умолчанию - вам нужен
-E
переключатель:Потому что (снова из справочной страницы):
Так что вы также можете использовать:
Так как скобки в данном случае излишни.
источник
Элегантная простота Bash, похоже, теряется в его огромной справочной странице.
В дополнение к превосходным решениям, описанным выше, я подумал, что постараюсь дать вам шпаргалку о том, как bash анализирует и интерпретирует утверждения . Затем, используя эту дорожную карту, я проанализирую примеры, представленные спрашивающим, чтобы помочь вам лучше понять, почему они не работают должным образом.
Примечание: строки сценария оболочки используются напрямую. Типизированные строки ввода сначала раскрываются в истории.
Каждая строка bash сначала маркируется токенами , или другими словами, врезается в так называемые токены . (Токенизация происходит перед всеми другими расширениями, включая фигурные скобки, тильду, параметр, команду, арифметику, процесс, разбиение слов и расширение имени файла.)
Токен здесь означает часть строки ввода, разделенную (разделенную) одним из следующих специальных метасимволов:
Bash использует много других специальных символов, но только эти 10 производят начальные токены.
Однако, поскольку эти метасимволы также иногда должны использоваться в токене, должен быть способ убрать их особое значение. Это называется побег. Экранирование осуществляется либо процитировать строки из одного или нескольких символов (то есть
'xx..'
,"xx.."
), или предваряя индивидуальный характер с задними косыми чертами, (т.е.\x
). (Это немного сложнее, чем это, потому что кавычки также должны быть заключены в кавычки, и потому что двойные кавычки не заключают в кавычки все, но это упрощение пока подойдет.)Не путайте цитирование bash с идеей цитирования строки текста, как в других языках. То, что находится между кавычками в bash, это не строки, а разделы входной строки, у которых экранированы метасимволы, чтобы они не разделяли токены.
Обратите внимание, между ними есть важное различие
'
,"
но это касается другого дня.Оставшиеся неэкранированные метасимволы становятся разделителями токенов.
Например,
В первом примере есть два токена, создаваемых разделителем пробелов:
echo
иxyz
.Аналогично во 2-м примере.
В третьем примере точка с запятой избежали, таким образом , есть 4 жетоны , полученные космическим разделителем,
echo
,x;
,echo
, иy
. Первый токен затем запускается как команда и принимает следующие три токена в качестве входных данных. Обратите внимание, 2-йecho
не выполняется.Важно помнить о том , что Баш сначала ищет вылетающие символы (
'
,"
и\
), а затем ищет неэкранированные разделители меты-символы, в этом порядке.Если не удалось избежать, то эти 10 специальных символов служат
token
разделителями. Некоторые из них также имеют дополнительное значение, но, в первую очередь, они являются разделителями токенов.Что ожидает grep
В приведенном выше примере Grep нужны эти маркеры,
grep
,string
,filename
.Первая попытка вопроса была:
В этом случае
(
,)
и|
являются неэкранированные символы мета и поэтому служат для разделения входа в эти маркеры:grep
,(
,then
,|
,there
,)
, иx.x
. Grep хочет видетьgrep
,then|there
иx.x
.Вторая попытка вопроса была:
Это размечает в
grep
,(then|there)
,x.x
. Вы можете увидеть это, если вы замените grep на echo:источник