Почему `grep fil *` терпит неудачу?

9

Я нашел echo file|grep fil*неудачи, но все echo abcd|grep abc*получилось.

Я не понимаю, кто-то может объяснить?

tmpbin
источник
Можете ли вы добавить систему и версию grep? Это связано с тем, что в gnugrep 2.16 (в Ubuntu 14.04 LTS) он не генерирует никаких ошибок (код выхода 0) и соответствует первым трем буквам. Например, echo file|grep fil*ответы с filэл.
Хастур
3
@Hastur Проблема вызвана расширением имени файла перед регулярным выражением. Мой рабочий каталог содержит файл с префиксом fil, но не файл с префиксом abc, поэтому fil * заменяется именем файла, но abc * не изменяется.
tmpbin
Спасибо, я не думал об этом. Когда я делаю свои попытки, я пробую их в новом каталоге ...
Hastur

Ответы:

31

В вашем примере есть две проблемы.

Основным из них является то, что вы предполагаете, что регулярные выражения работают так же, как шаблоны glob, в которых *используется подстановочный знак, означающий «любая последовательность символов». В регулярных выражениях *вместо этого означает «любое число предыдущего атома», поэтому fil*означает, что fза ним iследует ноль или более lсимволов. Вы должны сказать, grep fil.*чтобы получить предполагаемое значение: .означает «любой отдельный символ, так что это .*означает« любая последовательность символов ».

Меньшая проблема заключается в том, что вы используете специальные символы без кавычек, которые что-то значат в правилах glob, что означает, что оболочка может их интерпретировать. Если у вас есть какие-либо файлы в локальном каталоге, соответствующие шаблонам glob fil*или abc*, оболочка будет их расширять , поэтому grepполучит расширенные имена файлов в виде шаблона, а не предполагаемого RE. Всякий раз , когда вы используете такие символы в командной строке, вы должны процитировать их: echo file | grep 'fil.*'.

Уоррен Янг
источник