Как я могу grep для того или иного (2 вещи) в файле?

У меня есть файл, который имеет «then» и «there».

Я могу

$ 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)
26 голосов | спросил Michael Durrant 14 J000000Sunday13 2013, 20:01:56

4 ответа


40

Вам нужно поставить выражение в кавычки. Ошибка, которую вы получаете, является результатом bash, интерпретирующего ( как специальный символ.

Кроме того, вам нужно сообщить grep, чтобы использовать расширенные регулярные выражения.

$ grep -E '(then|there)' x.x

Без расширенных регулярных выражений вам необходимо выйти из |, ( и ). Обратите внимание, что здесь мы используем одинарные кавычки. Бэш специально обращается с обратной косой чертой в двойных кавычках.

$ grep '\(then\|there\)' x.x

В этом случае группировка не нужна.

$ grep 'then\|there' x.x

Было бы необходимо что-то вроде этого:

$ grep 'the\(n\|re\)' x.x
ответил Smith John 14 J000000Sunday13 2013, 20:10:40
7

Просто быстрое добавление, большинство ароматов имеют команду egrep, которая является только grep с -E. Мне лично гораздо лучше набрать

egrep "i(Pod|Pad|Phone)" access.log

Чем пользоваться grep -E

ответил Trausti Thor 14 J000000Sunday13 2013, 21:30:45
2

Материал, задокументированный REGULAR EXPRESSIONS на странице (или, по крайней мере, моей), на самом деле предназначен для extended regexps;

  

grep понимает три разные версии регулярного выражения   синтаксис: «basic», «extended» и «perl». В GNU grep нет   разница в доступных          функциональность между базовыми и расширенными синтаксисами. В других реализациях основные регулярные выражения менее эффективны. The   следующее описание относится к          расширенные регулярные выражения; различия для основных регулярных выражений суммируются впоследствии.

Но grep не использует их по умолчанию - вам нужен переключатель -E:

grep "(then|there)" x.x

Потому что (со страницы man снова):

  

Основные и расширенные регулярные выражения

     

В основных регулярных выражениях метасимволы?, +, {, |, (, и) теряют свое особое значение; вместо этого используйте версии с обратной косой чертой   \ ?, +, {, \ |, (, и          ).

Итак, вы также можете использовать:

grep "then\|there" x.x

Так как в этом случае скобки являются излишними.

ответил goldilocks 14 J000000Sunday13 2013, 20:11:23
0

Элегантная простота Баша, кажется, затерялась на огромной странице руководства.

В дополнение к превосходным решениям выше, я думал, что попытаюсь дать вам чит-лист на , как bash анализирует и интерпретирует утверждения . Затем, используя эту дорожную карту, я проанализирую примеры, представленные экспертом, чтобы помочь вам лучше понять, почему они не работают должным образом.


Примечание. Строки сценария оболочки используются напрямую. Типированные входные строки сначала расширены по истории.

Каждая строка bash сначала символизируется , или, другими словами, рубится на так называемые токены . (Tokenizing происходит перед всеми другими расширениями, включая скобки, тильду, параметр, команду, арифметику, процесс, разбиение слов и расширение имени файла.)

Символ здесь означает часть входной строки, разделенной (разделенной) одним из этих специальных метасимволов:

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

Аналогично во втором примере.

В третьем примере точка с запятой экранирована, поэтому есть 4 токена, создаваемых разделителем пробелов, echo, x;, echo и y. Первый токен затем запускается как команда и принимает следующие три токена в качестве входных данных. Обратите внимание, что второй echo не выполняется.


Важно помнить, что bash сначала ищет экранирующие символы (', " и \), а затем ищет неограниченные метасимвольные разделители, в этом порядок.

Если это не экранировано, эти 10 специальных символов служат в качестве разделителей token. Некоторые из них также имеют дополнительное значение, но в первую очередь это маркеры.


Что ожидает grep

В приведенном выше примере grep нуждается в этих токенах, grep, string, filename.

Первая попытка вопроса:

  
    

$ grep (тогда | там) x.x

  

В этом случае (, ) и | являются неэкранированными метасимволами и поэтому служат для разделения входа на эти токены: grep, (, then, |, there, ) и x.x , grep хочет видетьgrep, then|there и x.x

Вторая попытка вопроса:

  
    

grep "(тогда | там)" x.x

  

Этот токенизирует в grep, (then|there), x.x. Вы можете увидеть это, если вы замените grep для эха:

  
    

echo "(тогда | там)" x.x
    (тогда | там) x.x

  
ответил Eliptical view 30 SatEurope/Moscow2017-12-30T03:41:23+03:00Europe/Moscow12bEurope/MoscowSat, 30 Dec 2017 03:41:23 +0300 2017, 03:41:23

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132