Вопрос о командах оболочки и grep - PullRequest
3 голосов
/ 06 мая 2011

Кто-нибудь знает почему

grep "p\{2\}" textfile

найдет "яблоко", если оно есть в файле, но

grep p\{2\} textfile

не будет?

Я новичок в использовании командной строки и регулярных выражений, и это меня озадачивает.

Ответы [ 5 ]

2 голосов
/ 06 мая 2011

Хотя на этот вопрос уже дан ответ, но, поскольку вы новичок во всем этом, вот как его отладить:

- получить pid текущей оболочки (используя ps).

 PID TTY          TIME CMD

 1611 pts/0    00:00:00 su

 1619 pts/0    00:00:00 bash

 1763 pts/0    00:00:00 ps

- из какой-то другой оболочки подключите strace (трассировщик системных вызовов) к необходимому pid (здесь 1619):

strace -f -o <output_file> -p 1619

- Запустите обе команды, которые вы пробовали

- откройте выходной файл и найдите вызовы семейства exec для требуемого процесса, здесь: grep

Вывод на моей машине выглядит примерно так:

1723  execve("/bin/grep", ["grep", "--color=auto", "p{2}", "foo"], [/* 19 vars */]) = 0

1725  execve("/bin/grep", ["grep", "--color=auto", "p\\{2\\}", "foo"], [/* 19 vars */]) = 0

Теперь вы видите разницу в том, как grep был выполнен в обоих случаях, и можете сами определить проблему. :)

все же загадку -e флага еще предстоит решить ....

1 голос
/ 06 мая 2011

Без кавычек оболочка попытается расширить параметры.В вашем случае фигурные скобки '{}' имеют особое значение в оболочке, очень похожее на звездочку '*', которая расширяется до подстановочного знака.

0 голосов
/ 07 мая 2011

Первый обрабатывает шаблон с помощью регулярных выражений, затем pp:

echo "apple" | grep 'p\{2\}'

Второй буквально обрабатывает шаблон, затем p{2}:

echo "ap{2}le" | grep p\{2\}
0 голосов
/ 06 мая 2011

со страницы руководства grep

In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \).

так что эти два становятся функциональным эквивалентом

egrep p{2} 

и

grep "p\{2\}" 

первый использует ERE (расширенные регулярные выражения), второй использует BRE (базовые регулярные выражения) в вашем примере, потому что вы используете grep (который поддерживает BRE, когда вы не используете ключ -e) и заключены в кавычки поэтому "\ {" раскрывается как специальный символ BRE.

Ваш второй экземпляр не работает, потому что вы просто ищете буквальную строку 2 {p}, которой нет в вашем файле

вы можете продемонстрировать, что grep расширяет вашу строку как BRE, попробовав:

grep "p\{2"

grep будет жаловаться

grep: Unmatched \{  
0 голосов
/ 06 мая 2011

С кавычками ваше полное регулярное выражение передается непосредственно в grep.Без кавычек grep видит ваше регулярное выражение как p{2}.

Редактировать:

Для пояснения, без кавычек ваши слэши удаляются оболочкой, прежде чем ваше регулярное выражение передается в grep.

Попробуйте:

echo grep p\{2\} test.txt

И ваш вывод будет выглядеть как ...

grep p{2} test.txt

Кавычки не позволяют оболочке экранировать символы до того, как они попадут в grep.Вы также можете избежать косой черты, и это будет работать без кавычек - grep p\\{2\\} test.txt

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...