Оператор grep "+" не працює


31

Це

ls -l /var/log | awk '{print $9}' | grep "^[a-z]*\.log."

Виводить це:

alternatives.log.1
alternatives.log.10.gz
alternatives.log.2.gz
alternatives.log.3.gz
alternatives.log.4.gz
alternatives.log.5.gz
alternatives.log.6.gz
alternatives.log.7.gz
alternatives.log.8.gz
alternatives.log.9.gz
apport.log.1
apport.log.2.gz
apport.log.3.gz

але це:

ls -l /var/log | awk '{print $9}' | grep "^[a-z]+\.log."

виводить нічого.

Чому? Я просто змінився *на +. Хіба це не схоже? Оператору +потрібно лише хоча б одну відповідність і *нуль або більше.

Відповіді:


36

Це тому, що grep(без жодних аргументів) працює лише зі стандартними регулярними виразами. +є частиною розширених регулярних виразів, тому для цього потрібно використовувати grep -Eабо egrep:

ls -l /var/log | awk '{print $9}' | grep -E "^[a-z]+\.log."

Крім того, ви можете просто зробити це, якщо ви не хочете використовувати розширені регулярні вирази:

ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."

Спасибі. Я зараз про це рішення, але мені було цікаво, чому "+" не працює. Тепер я знаю. Знову дякую.
Марко

11

Щоб детальніше відповісти на MiJyns, "спеціальні символи", як +, також працюють у стандартному регулярному вираженні, але вам потрібно уникнути їх з зворотним нахилом. Можна сказати, очікування за замовчуванням змінюється між стандартним та розширеним регулярним виразом:

У стандартному регулярному вираженні символи за замовчуванням відповідають буквально. Наприклад, у grep "ab+"+ є буквальним +. Регекс, наприклад, знайде "ab + ab", але не "abbbb". Щоб використовувати "спеціальне значення" +, вам потрібно уникнути цього. Так grep "ab\+"би знайти "abbb", але більше не "ab + ab". Оскільки в останньому прикладі + інтерпретується як кількісний показник "один або багато з того", у такому випадку "один або багато b".

У розширеному регулярному вираженні це точно навпаки. Тут вам потрібно уникнути "особливих символів", щоб до них ставились буквально. Так grep -E "ab+"знаходить "abbb", але не "ab + ab". Якщо ви уникнете знака +, воно збігається буквально. Так grep -E "ab\+"знаходить "ab + ab", але не "abbb".


1
Який спадок безладно ... ;-), як магія та супермагічний перегляд in vim. Урх. Ціна, яку потрібно заплатити за зворотну сумісність ...
Rmano
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.