Как использовать "grep" для имени файла вместо содержимого файла?


135

grep используется для поиска в файле, чтобы увидеть, соответствует ли какая-либо строка заданному регулярному выражению. Однако у меня такая ситуация - я хочу написать регулярное выражение, которое будет соответствовать самому имени файла (а не содержимому файла). Я запущу это из корневого каталога системы, чтобы найти все те файлы, которые соответствуют регулярному выражению.

Например, если я хочу найти все файлы форм VB, которые начинаются с «f» и заканчиваются на .frm, я буду использовать регулярное выражение -

   "f[[:alnum:]]*\.frm"

Может ли grep это сделать? Если нет, есть ли утилита, которая позволила бы мне это сделать? Спасибо.

Ответы:


120

В этом случае вам нужно использовать findвместо grep.

Вы также можете использовать findв сочетании с grepили egrep:

$ find | grep "f[[:alnum:]]\.frm"

12
В этом нет необходимости. В Find есть эта функция, встроенная в -regexопцию.
whereswalden

4
здесь нет необходимости, но grep поддерживает регулярное выражение perl, а find - нет.
Дэн

2
Нет, вы можете использовать grep. Это проще, чем использовать find. Добавьте переключатель «-rl», и он будет искать имя файла вместо файла. Смотрите мой пост ниже.
RM

@ alpha_989, я сказал, что grep поддерживает его, что он и делает: gnu.org/software/grep/manual/html_node/… точка подключения к grep нужна только в том случае, если вам нужен pcre. где уресвальден есть правильный ответ
Дэн

60

пример

find <path> -name *FileName*

Из руководства:

find -name шаблон

База имени файла (путь с удаленными ведущими каталогами) соответствует шаблону оболочки. Поскольку ведущие каталоги удаляются, имена файлов, рассматриваемые для сопоставления с -name, никогда не будут содержать косую черту, поэтому «-name a / b» никогда не будет соответствовать чему-либо (вам, вероятно, потребуется вместо этого использовать -path). Метасимволы («*», «?» И «[]») соответствуют «.» в начале базового имени (это изменение в find‐ utils-4.2.2; см. раздел «СООТВЕТСТВИЕ СТАНДАРТАМ» ниже). Чтобы игнорировать каталог и файлы в нем, используйте -prune; см. пример в описании -path. Фигурные скобки не считаются особенными, несмотря на то, что некоторые оболочки, включая Bash, наделяют фигурные скобки особым значением в шаблонах оболочки. Сопоставление имени файла выполняется с использованием библиотечной функции fnmatch (3). Не забудьте заключить шаблон в кавычки, чтобы защитить его от расширения оболочкой.


2
Я нашел этот ответ самым полезным. Я добавил пару дополнительных опций: find . -maxdepth 1 -name "*filename*" -print
JSON C11

47

Как сказал Пабло, вам нужно использовать findвместо grep, но нет никакой необходимости трубы findк grep. findимеет встроенную функциональность:

find . -regex 'f[[:alnum:]]\.frm'

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


1
Я бы добавил очень удобную функцию поиска по дате с помощью -mtimeи-mmin
Johnride

1
Кроме того, переключатель -regex выполняет сопоставление со всем путем. Поэтому для работы в примере необходимо добавить. * В начале регулярного выражения.
tumasgiu

15

Вы можете найти полный путь к файлу с помощью grep, просто перенаправьте вывод дерева

tree -f | grep filename

Вот функция, которую вы можете поместить в свой .bash_profile или .bashrc

findfile(){ tree -f | grep $1; } # $1 = filename, -f is full path

-f не является обязательным.
jasonleonhard

10
find -iname "file_name"

Syntax :-
find -type type_descriptor file_name_here

type_descriptor типы: -

f: обычный файл

d: каталог

l: символическая ссылка

c: символьные устройства

b: блочные устройства


1
Я не могу использовать имя файла после -type typedescriptorодного. Это ошибка?
Allan Nørgaard

5

Вы также можете сделать:

tree | grep filename

Это направляет вывод команды tree в grep для поиска. Это только скажет вам, существует ли файл.


1

Нет, для этого отлично подходит grep:

 grep -rl "filename" [starting point]

 grep -rL "not in filename"

1
Это ищет в содержимом файла "имя файла", а затем печатает имена файлов с совпадениями. OP хочет, чтобы имена файлов совпадали, а не содержимое файла.
Мэтью

1
Согласовано, это не ищет имена файлов, а просто печатает имена файлов, для которых найдено совпадение содержимого . Вы неправильно поняли оба варианта -lи -L.
Прометей

2
+1 за то, что я именно то, что мне нужно. Счастлив, что мне не пришлось критиковать вопрос, чтобы найти ответ, который мне был нужен,
Александр МакНалти

-1

Также для нескольких файлов.

tree /path/to/directory/ | grep -i "file1 \| file2 \| file3"

-1

Самый простой способ

find . | grep test

здесь find будет рекурсивно перечислить все файлы в (.), то есть в текущем каталоге. И тогда это просто grep. появятся все файлы с именем "test".

вы можете играть с grep в соответствии с вашими требованиями. Примечание. Поскольку grep является общей классификацией строк, она может дать вам не только имена файлов. но если в пути есть каталог ('/xyz_test_123/other.txt'), он также попадет в набор результатов. ура


Это найдет что-нибудь с "test" в пути, например ./foo/bar/latest/fred.txt.
Пол Р,

ой. Тот, о котором я не подумал. Спасибо за упоминание.
сачий
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.