2017-01-20 2 views
1

Я использую команду grep -r [text], чтобы рекурсивно найти текст, даже в комплекте с заархивированным файлом. Однако я обнаружил, что это не работает с выражением «*»:Почему «grep -r» не принимает «*»?

$ grep -r "*.cert" 

[nothing] 

$ grep -r "ca.cert" 

[entries found] 

Экранирование персонажа тоже не помогает. Почему это?

+1

Просто попробуйте 'grep -r '.cert $''. Это даст вам все записи, которые заканчиваются на '.cert' – sisanared

+0

@sisanared. Ваше предложение найдет шаблон только в конце строки. Если имя файла находится в некотором непрерывном тексте, хотя шаблон должен заканчиваться границей слова: '.. * \. Cert \> ''. Фактически, он должен исключать пробелы из имени файла, или он найдет всю строку до «.cert». Что-то вдоль '' [^ [: space:]] * \. Cert \> ''(untested). Предполагая, что имена файлов не могут содержать пробелы. –

ответ

7

Вы как-то путаете глобусы с регулярными выражениями. В grep выражение, которое вы ищете, является регулярным выражением, поэтому вы должны следовать его правилам.

При использовании функции globing, *, расширяется до любого персонажа.

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

Просто используйте . означает любой символ:

grep -r ".*\.cert" 
#  ^

Смотрите также, как я избежать второй точки, так что буквальное точка, а не метасимвол.

+0

Вы также можете избежать буквальной точки по той же логике. Я предполагаю, что файлы называются 'xy.cert' и т. Д. Ваше предложение: да. (Без побега шаблон найдет 'xyzcert', который, вероятно, не предназначен.) –

+0

@ PeterA.Schneider не очень, так как я использую его для соответствия любому символу. Но я вижу вашу точку зрения, возможно, мой ответ будет лучше с чем-то вроде '.. * \. Cert'', чтобы соответствовать тому, что следует за' .cert'. – fedorqui

+0

Фактически, если grep ищет имена файлов, и один не хочет найти, например. 'some.certmanual.doc' следует положить конец границе слова:' '. * \. cert \> '' –

1

Для обработки действительно произвольных имен файлов в * nix неожиданно сложно, гранича с невозможным. Чтобы получить впечатление: This и this от этого же автора.

Так что необходимо найти все файлы в форме «xy.cert», но только тех. Мы не хотим находить «xycert» или «xy.certificate».

Если мы можем считать имена файлов, которые не имеют пробела после «.cert» (например, «xy.cert my butt», который является законным именем файла в современных файловых системах), мы можем просто использовать '\.cert\>'. Это находит любое появление «.cert» с пробелом после него или в EOF. \> обозначает конец слова, так что «xy.certificate» не соответствует.

Если поиск файлов с именем «.cert» не нужен, мы должны сказать '[^[:space:]]+\.cert\>', как в моем комментарии. (Я изменил звездочку на плюс, чтобы обеспечить как минимум один пробел в имени файла перед точкой.) Я должен использовать egrep для этого шаблона.

+0

TL; DR: в потоке или тексте, чтобы найти имена файлов, расширение которых является 'cert', используйте' '\ .cert \> ''. – fedorqui

+0

@fedorqui Правильно ;-). Но, думая об этом, это может быть нежелательно - хотим ли мы найти файл с именем «.cert»? –

+1

Если вы не можете использовать 'egrep', просто избегайте' + ':' '[^ [: space:]] \ + \. Cert \>' '. – fedorqui

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