2015-02-11 2 views
1

Я уже давно изучал shell-скрипты, и я наткнулся на этот раздел руководства по основам Linux относительно grep и фигурных скобок {}. Моя проблема заключается в том, что когда я требую шаблон строки для поиска с использованием grep от минимального до максимального числа вхождений с помощью {} или фигурных скобок, мой результат превышает максимально указанный мной.Curly Braces с {} grep и регулярными выражениями: Почему это превышает максимальное значение?

Вот что случилось:

Express11:~/unix_training/reg_ex # cat reg_file2 
ll 
lol 
lool 
loool 
loooose 
Express11:~/unix_training/reg_ex # grep -E 'o{2,3}' reg_file2 
lool 
loool 
loooose 
Express11:~/unix_training/reg_ex # 

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

EDIT: На самом деле причина, по которой я не понимал, как работали фигурные скобки, объясняется этим упрощенным объяснением руководства. И я цитирую:

19.4.10. между n и m раз И здесь мы требуем ровно от минимум 2 до максимум 3 раза.

[email protected]:~$ cat list2 
ll 
lol 
lool 
loool 
[email protected]:~$ grep -E 'o{2,3}' list2 
lool 
loool 
[email protected]:~$ grep 'o\{2,3\}' list2 
lool 
loool 
[email protected]:~$ cat list2 | sed 's/o\{2,3\}/A/' 
ll 
lol 
lAl 
lAl 
[email protected]:~$ 

Спасибо всем, кто ответил.

+1

Отличная вещь в Google заключается в том, что она позволяет вам описать описание этого упрощенного объяснения в руководстве и узнать, к чему относится «руководство». На самом деле это не руководство; это книга под названием «Основы Linux» Пола Кобува, вводный текст для начинающих администраторов, который вообще не касается регулярных выражений. Существует справочная страница регулярного выражения (возможно, в вашей системе: попробуйте 'man 7 regex'), и в Интернете много ресурсов регулярных выражений. Некоторые из них даже не так уж плохи. – rici

+0

В этом специальном случае вы могли бы понять, что хотите 2, но не 4 последовательных 'o'. Поэтому вы можете использовать: 'grep oo reg_file2 | grep -v oooo'. –

ответ

5
# grep -E 'o{2,3}' reg_file2 
lool 
loool 
loooose 

Команда прекрасно работает, что она соответствует первым трем символам o в последней строке. Вот почему вы получаете последнюю строку в финальном выпуске.

Я думаю, что команда, которую вы на самом деле ищет это,

$ grep -P '(?<!o)o{2,3}(?!o)' file 
lool 
loool 

Объяснение:

  • (?<!o) отрицательна, который утверждает просмотра назад, что матч не будет предшествовать буква o.

  • o{2,3} Соответствует 2 или 3 o.

  • (?!o) Отрицательный взгляд, который утверждает, что за совпадением не последует буква o.

ИЛИ

$ grep -E '(^|[^o])o{2,3}($|[^o])' file 
lool 
loool 

Пояснение:

  • (^|[^o]) соответствует началу строки ^ или любой символ, но не o

  • o{2,3} Матчей 2 или 3 Выходов

  • ($|[^o]) сопоставляют конец строки $ или любой характер, но не o

+0

Благодарим вас за скромный отклик. – user3873164

+0

@ user3873164: в этом случае вы должны отметить ответ как принятый. –

1

Вы не ясно, как с регулярными выражениями работ.

Образец o{2,3} в grep будет проходить через каждую строку, ища oo и ooo, до тех пор, пока есть совпадение, Греп доставит вам эту линию. Так как вы не добавили другие правила в свой шаблон, то вы получаете от grep -E 'o{2,3}' reg_file2.

Я предполагаю, что в вашем случае вам нужно только две или три буквы подряд, так что вам нужно будет использовать регулярное выражение, как то, что Радж ответил. Соответствие oo или ooo, которое не следует ни за буквой «o», ни за ней.

+0

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

Смежные вопросы