Къдрави скоби с {} grep и регулярни изрази: Защо надвишава максималната стойност?

От известно време се самообучавам по скриптиране на обвивка и попаднах на този раздел от ръководството за основите на Linux относно grep и фигурни скоби {}. Проблемът ми е, че когато изисквам низов модел за търсене с помощта на 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 #

Когато според ръководството не би трябвало да е така, тъй като тук уточнявам, че търся само низове, съдържащи две последователни o до три последователни o.

РЕДАКТИРАНЕ: Всъщност причината, поради която не разбрах как работят фигурните скоби, беше това опростено обяснение в ръководството. И цитирам:

19.4.10. между n и m пъти И тук изискваме точно от минимум 2 до максимум 3 пъти.

paul@debian7:~$ cat list2
ll
lol
lool
loool
paul@debian7:~$ grep -E 'o{2,3}' list2
lool
loool
paul@debian7:~$ grep 'o\{2,3\}' list2
lool
loool
paul@debian7:~$ cat list2 | sed 's/o\{2,3\}/A/'
ll
lol
lAl
lAl
paul@debian7:~$

Благодаря на всички, които отговориха.


person user3873164    schedule 11.02.2015    source източник
comment
Страхотното нещо на Google е, че ви позволява да вземете описание като това опростено обяснение от ръководството и да разберете какво ръководство се споменава. Всъщност това изобщо не е ръководство; това е книга, наречена Linux Fundamentals от Paul Cobbaut, уводен текст за начинаещи администратори, който изобщо не е специално за регулярните изрази. Има страница с ръководство за регулярни изрази (вероятно във вашата система: опитайте man 7 regex) и има много ресурси за регулярни изрази в мрежата. Някои от тях дори не са много лоши.   -  person rici    schedule 11.02.2015
comment
В този специален случай можете да разберете, че искате 2, но не 4 последователни os. Така че можете да използвате: grep oo reg_file2 | grep -v oooo.   -  person gniourf_gniourf    schedule 11.02.2015


Отговори (2)


# 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]) Съвпада с края на ред $ или който и да е знак, но не и от o

person Avinash Raj    schedule 11.02.2015
comment
Благодаря ви за скромния отговор. - person user3873164; 11.02.2015

Не сте наясно как работи регулярният израз.

Моделът o{2,3} в grep ще премине през всеки ред, търсейки oo и ooo, стига да има съвпадение, Grep ще ви осигури този ред. Тъй като не сте добавили други правила във вашия шаблон, това, което получавате от grep -E 'o{2,3}' reg_file2, е правилно.

Предполагам, че във вашия случай искате само две или три последователни букви "o", следователно ще трябва да използвате регулярен израз като това, което Радж отговори. Съвпадение на oo или ooo, което нито следва, нито следва буквата „o“.

person Lution    schedule 11.02.2015
comment
Благодаря за бързата реакция. Редактирах въпроса си и започнах да използвам регулярни изрази само за една седмица въз основа на основно ръководство. - person user3873164; 11.02.2015