Як "grep" для імені файлу замість вмісту файлу?


135

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

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

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

Чи може це зробити греп? Якщо ні, чи є утиліта, яка дозволила б мені це зробити? Дякую.

Відповіді:


120

Використовувати потрібно findзамість grepцього випадку.

Ви можете також використовувати findв поєднанні з grepабо egrep:

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

12
Це зайве. Find має вбудовану функціональність за допомогою цієї -regexопції.
whereswalden

4
Тут непотрібно, але grep підтримує регулярний вираз perl, тоді як знайти його немає.
Ден

2
Ні, ви можете використовувати grep. Шлях простіше, ніж використання пошуку. Додайте перемикач "-rl", і він буде шукати ім'я файлу замість файлу. Дивіться мою публікацію нижче.
РМ

@ alpha_989, я сказав, що grep підтримує це, що це робить: gnu.org/software/grep/manual/html_node/… пункт передання на grep потрібен лише у тому випадку, якщо вам потрібен pcre. whereswalden має правильну відповідь
Dan

60

Приклад

find <path> -name *FileName*

З посібника:

find -name шаблон

База імені файлу (шлях з вилученими провідними каталогами) відповідає шаблону оболонки. Оскільки провідні каталоги видалені, імена файлів, що розглядаються для відповідності з -name, ніколи не включатимуть косу рису, тому "-name a / b" ніколи не відповідатиме жодному (вам, напевно, потрібно використовувати -path). Метахарактеристики ("*", "?" Та "[]") відповідають "." на початку базової назви (це зміна знахідки-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це дуже потужна програма для пошуку файлів по імені та підтримує пошук за типом файлу, обмеження глибини, поєднання різних пошукових термінів із булевими операціями та виконання довільних команд на знайдених файлах. Додаткову інформацію див. На сторінці пошуку .


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 type: -

f: звичайний файл

d: каталог

l: символічне посилання

c: символьні пристрої

б: блокувати пристрої


1
Я, здається, не можу використовувати ім’я файлу, що слід -type typedescriptorодне. Це помилка?
Allan Nørgaard

5

Ви також можете зробити:

tree | grep filename

Це передає висновок команди дерева для пошуку для пошуку. Це лише скаже вам, чи існує файл.


1

Ні, grep для цього спрацьовує чудово:

 grep -rl "filename" [starting point]

 grep -rL "not in filename"

1
При цьому виконується пошук вмісту файлу для "ім'я файлу", після чого друкуються назви файлів із збігами. ОП хоче назвати файли відповідності, а не вміст файлів.
Метью

1
Погоджено, це не шукає назви файлів, воно просто виводить назви імен файлів, для яких знайдено відповідність вмісту . Ви значно неправильно зрозуміли -lі -Lваріанти, і варіанти.
Прометей

2
+1 за те, що я саме те, що мені потрібно. Щасливий, що мені не довелося критикувати питання, щоб знайти потрібну мені відповідь
Олександр МакНулті

-1

Також для декількох файлів.

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

-1

Найпростіший спосіб

find . | grep test

тут знайдеться список усіх файлів у (.), тобто поточному каталозі, рекурсивно. І тоді це просто простий греп. всі файли, назва яких має "тест", з'являться.

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


Це знайде щось із "тестом" на шляху, наприклад ./foo/bar/latest/fred.txt.
Пол Р.

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