Как работает это [t] хриплое скобочное выражение в grep?

38

Я видел эту однострочную:

$ ps -ef | grep [f]irefox 

thorsen   16730     1  1 Jun19 ?        00:27:27 /usr/lib/firefox/firefox ...

Таким образом, кажется, что он возвращает список процессов с «firefox» в данных, но опускает сам процесс grep, и поэтому кажется примерно эквивалентным:

ps -ef |grep -v grep| grep firefox

Я не могу понять, как это работает, хотя. Я посмотрел на справочную страницу по grep и в других местах, но не нашел объяснения.

И составить тайну, если я бегу:

$ ps -ef | grep firefox  > data
$ grep [f]irefox data

thorsen   15820 28618  0 07:28 pts/1    00:00:00 grep --color=auto firefox
thorsen   16730     1  1 Jun19 ?        00:27:45 /usr/lib/firefox/firefox ....

[т] Рик, кажется, перестает работать!

Кто-то здесь будет знать, что происходит, я уверен.

Спасибо.

Торсен
источник
Хм, ты уверен, что это правильно? ps -eaf | grep [fF] irefox будет иметь больше смысла. Это выглядит как регулярное выражение и означает совпадение с любым из вложенных символов. Может быть сделано также как диапазон, например, [0-9]
мбс
Ну да. Это была моя проблема: класс персонажей, содержащий только одного персонажа, казался бессмысленным, но производил «таинственный» побочный эффект! В любом случае, Джокердино дал хорошее объяснение.
Торсен

Ответы:

57

Выражение в квадратных скобках является частью соответствия шаблонов классов символов grep (а также других оболочек) .

grepПрограмма по умолчанию понимает POSIX основных регулярных выражений. С этим вы можете определить классы персонажей. Например, ps -ef | grep [ab9]irefoxможно найти « a irefox», « b irefox», « 9 irefox», если таковые существуют, но не « ab irefox».

Команда grep [a-zA-Z0-9]irefoxдаже найдет все процессы, которые начинаются с ровно одной буквы или числа и заканчиваются на «irefox».

Так что ps -ef | grep firefoxищет строки с firefoxв нем. Поскольку в самом процессе grep есть «firefox», grep также находит это. Добавляя a [], мы ищем только класс символов "[f]" (который состоит только из буквы "f" и поэтому эквивалентен просто "f" без скобок). Преимущество скобок теперь состоит в том, что строка «firefox» больше не появляется в команде grep. Следовательно, сам grep не будет отображаться в результате поиска.

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

Если вы хотите исправить второй результат, вы можете использовать их следующим образом:

ps -ef | grep [f]irefox  > data
grep firefox data

(Ссылка)

Джокердино
источник
1
Хм. Мне не приходило в голову, что [] что-то интерпретируется оболочкой, ДО того, как grep даже получит шанс. Спасибо за объяснение. Все [м] истерики решены.
Торсен
Рад был помочь.
Хорошего
1
В bash квадратные скобки будут переданы grep, если нет совпадения со словом, в котором они находятся (т.е. в текущем каталоге нет файла с именем «firefox»). Однако, у grep также есть классы символов, и [f] в grep такой же, как f.
Даниэль Гершкович
6
На самом деле в этом случае я не думаю, что это интерпретируется оболочкой перед grep. Я думаю, [f]это скобка соответствия шаблону регулярного выражения для классов символов. Как и в «[a-z0-9] irefox», grep будет также соответствовать «airefox» и «0irefox». Вы можете легко увидеть, что это не встроенный bash, так как echo $([f])возвращает ошибку.
con-f-use
4
Конкретная причина [f]irefoxработает для этой цели в том, что она не раскрывается оболочкой. Когда оболочка расширяется [f]irefoxдо firefox, это заставляет grepвидеть firefox, а затем firefoxявляется частью grepкомандной строки России, точно так же, как если бы они grep firefoxбыли запущены. Но это хорошо , чтобы сохранить оболочки сопоставления с образцом в виде , в частности , когда сценарии, потому что , если есть файл с именем firefoxв текущем каталоге , то оболочка имеет расширение [f]irefoxкfirefox и этому методу не удается, то есть, по grepлинии от psпоказан.
Элия ​​Каган,
10

Причина в том, что строка

grep firefox

соответствует шаблону firefox, но строка

grep [f]irefox

не соответствует шаблону [f]irefox(что эквивалентно шаблону firefox).

Вот почему первый grep соответствует собственной командной строке процесса, а второй - нет.

Даниил Гершкович
источник
Это заставляет мою голову болеть еще сильнее
Pithikos