Элегантная простота Bash, похоже, теряется в его огромной справочной странице.
В дополнение к превосходным решениям, описанным выше, я подумал, что постараюсь дать вам шпаргалку о том, как bash анализирует и интерпретирует утверждения . Затем, используя эту дорожную карту, я проанализирую примеры, представленные спрашивающим, чтобы помочь вам лучше понять, почему они не работают должным образом.
Примечание: строки сценария оболочки используются напрямую. Типизированные строки ввода сначала раскрываются в истории.
Каждая строка bash сначала маркируется токенами , или другими словами, врезается в так называемые токены . (Токенизация происходит перед всеми другими расширениями, включая фигурные скобки, тильду, параметр, команду, арифметику, процесс, разбиение слов и расширение имени файла.)
Токен здесь означает часть строки ввода, разделенную (разделенную) одним из следующих специальных метасимволов:
space, - White space...
tab,
newline,
‘<’, - Redirection & piping...
‘|’,
‘>’
‘&’, - And/Both < | > | >> .or. &<file descriptor>
‘;’, - Command termination
‘(’, - Subshell, closed by - ‘)’
Bash использует много других специальных символов, но только эти 10 производят начальные токены.
Однако, поскольку эти метасимволы также иногда должны использоваться в токене, должен быть способ убрать их особое значение. Это называется побег. Экранирование осуществляется либо процитировать строки из одного или нескольких символов (то есть 'xx..', "xx.."), или предваряя индивидуальный характер с задними косыми чертами, (т.е. \x). (Это немного сложнее, чем это, потому что кавычки также должны быть заключены в кавычки, и потому что двойные кавычки не заключают в кавычки все, но это упрощение пока подойдет.)
Не путайте цитирование bash с идеей цитирования строки текста, как в других языках. То, что находится между кавычками в bash, это не строки, а разделы входной строки, у которых экранированы метасимволы, чтобы они не разделяли токены.
Обратите внимание, между ними есть важное различие ', "но это касается другого дня.
Оставшиеся неэкранированные метасимволы становятся разделителями токенов.
Например,
$ echo "x"'y'\g
xyg
$ echo "<"'|'\>
<|>
$ echo x\; echo y
x; echo y
В первом примере есть два токена, создаваемых разделителем пробелов: echoи xyz.
Аналогично во 2-м примере.
В третьем примере точка с запятой избежали, таким образом , есть 4 жетоны , полученные космическим разделителем, echo, x;, echo, и y. Первый токен затем запускается как команда и принимает следующие три токена в качестве входных данных. Обратите внимание, 2-й echoне выполняется.
Важно помнить о том , что Баш сначала ищет вылетающие символы ( ', "и \), а затем ищет неэкранированные разделители меты-символы, в этом порядке.
Если не удалось избежать, то эти 10 специальных символов служат tokenразделителями. Некоторые из них также имеют дополнительное значение, но, в первую очередь, они являются разделителями токенов.
Что ожидает grep
В приведенном выше примере Grep нужны эти маркеры, grep, string, filename.
Первая попытка вопроса была:
$ grep (тогда | там) xx
В этом случае (, )и |являются неэкранированные символы мета и поэтому служат для разделения входа в эти маркеры: grep, (, then, |, there, ), и x.x. Grep хочет видеть grep, then|thereи x.x.
Вторая попытка вопроса была:
grep "(тогда | там)" xx
Это размечает в grep, (then|there), x.x. Вы можете увидеть это, если вы замените grep на echo:
эхо "(тогда | там)" хх
(тогда | там) хх