Знайдіть усі файли з іменем, що містить рядок


177

Я шукав команду, яка повертає файли з поточного каталогу, які містять рядок у імені файлу. Я бачив locateі findкоманди, які можуть знайти файли, що починаються з чогось first_word*або закінчуються чимось *.jpg.

Як я можу повернути список файлів, що містять рядок у назві файлу?

Наприклад, якщо 2012-06-04-touch-multiple-files-in-linux.markdownбув файл у поточному каталозі.

Як я міг повернути цей файл та інші, що містять рядок touch? Використання такої команди, якfind '/touch/'


питання бентежить. Ви хочете знайти файли, що містять рядок, або файли, імена яких містять вказаний рядок? на перше запитання відповідає man grep, на друге - man find. чому ви б google замість того, щоб використовувати людину, я не знаю.
просто хтось

1
Дякую! У першому реченні не вказано, чи є вміст файлу чи ім'я файлу. Оновлено.
Друга

Відповіді:


303

Використання find:

find . -maxdepth 1 -name "*string*" -print

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

Якщо ви хочете уникнути файлу, що містить ':', ви можете ввести:

find . -maxdepth 1 -name "*string*" ! -name "*:*" -print

Якщо ви хочете використовувати grep(але я думаю, що це не потрібно, оскільки ви не хочете перевіряти вміст файлу), ви можете використовувати:

ls | grep touch

Але, повторюю, find- це краще і більш чітке рішення для вашої задачі.


Дякую @Zagorax. Це робить саме так. Бажане команда не так довго , але ayee :)
Dru

2
@Dru, Змінено для висвітлення справи, якщо ви хочете уникати колонок. findце дуже потужний інструмент, він повинен бути якось "довгим". :)
Zagorax

Дякую, що перший зробив це прекрасно, не повертаючи жодного вмісту.
Друга

3
@Dru, якщо ви хочете, щоб він був "коротшим", ви можете уникнути, -printоскільки це поведінка за замовчуванням, і .оскільки це тека за замовчуванням, де вона перевіряється.
Zagorax

1
find . -name "*string*"Також чудово працює. Видалення .кидає помилку на мій кінець. Ще раз дякую @Zagorax.
Друг

14

Використовуйте греп наступним чином:

grep -R "touch" .

-Rозначає рецидив. Якщо ви бажаєте не входити в підкаталоги, тоді пропустіть його.

-iозначає "ігнорувати випадок". Ви також можете спробувати це.


Чудово. Я помітив, що деякий вміст файлу слідує за :. Чи все-таки це можна відмовити? Можливо, використовуєте варіант?
Друга

1
Спробуйте:grep -R "touch" . | cut -d ":" -f 2
carlspring

Це, здається, створює лише вміст файлів. Ви, по суті, відповіли на моє запитання, але я можу спробувати виконати копання, щоб утримати вміст.
Друга

Ах ... вам потрібні лише імена файлів? Виконати: grep -R "touch" . | cut -d ":" -f 1 (вибачте, що вас неправильно прочитали).
carlspring

Дякую @carlspring це цікаво. grepабо повертає файли із вмістом і назви файлів, що містять, touchабо вміст, що містить touch, але я не впевнений, у тому випадку. Зі списку повернених файлів половина містить touchв заголовку, а друга половина конатинів touchу тілі, а не заголовок. Щойно це зрозумів.
Друга

5

-maxdepthОпція повинна бути перед -nameопцією, як показано нижче.,

find . -maxdepth 1 -name "string" -print

1
Ви повинні поставити * до і після "рядка".
Ерін

3
find $HOME -name "hello.c" -print

Це дозволить здійснити пошук у всій системі $HOME(тобто /home/username/) для будь-яких файлів з назвою "hello.c" та відобразити їх імена шляхів:

/Users/user/Downloads/hello.c
/Users/user/hello.c

Однак це не збігається HELLO.Cабо HellO.C. Для відповідності регістру невідчутним є -inameнаступний варіант:

find $HOME -iname "hello.c" -print

Приклади виходів:

/Users/user/Downloads/hello.c
/Users/user/Downloads/Y/Hello.C
/Users/user/Downloads/Z/HELLO.c
/Users/user/hello.c

Передайте -type fможливість лише шукати файли:

find /dir/to/search -type f -iname "fooBar.conf.sample" -print
find $HOME -type f -iname "fooBar.conf.sample" -print

-inameПрацює або на GNU або BSD (включаючи OS X) команду версії пошуку. Якщо ваша версія команди find не підтримує -iname, спробуйте наступний синтаксис за допомогою grepкоманди:

find $HOME | grep -i "hello.c"
find $HOME -name "*" -print | grep -i "hello.c"

АБО спробуйте

find $HOME -name '[hH][eE][lL][lL][oO].[cC]' -print

Приклади виходів:

/Users/user/Downloads/Z/HELLO.C
/Users/user/Downloads/Z/HEllO.c
/Users/user/Downloads/hello.c
/Users/user/hello.c

0

Якщо рядок знаходиться на початку імені, ви можете це зробити

$ compgen -f .bash
.bashrc
.bash_profile
.bash_prompt

3
compgenне є відповідним молотком для цього цвяха. Цей мало використовуваний інструмент призначений для переліку доступних команд , і як такий, він перераховує файли в поточному каталозі (які можуть бути сценаріями), і він не може ні повторюватись, ні переглядати минуле початку імені файлу, ні шукати вміст файлу, роблячи його переважно марно.
мсанфорд

0

Альтернативою багатьом уже наданим рішенням є використання глобуса **. Якщо ви користуєтесь bashопцією globstar( shopt -s globstar) або користуєтесь нею zsh, ви можете просто використовувати глобус **для цього.

**/bar

здійснює пошук рекурсивного каталогу у файлах з назвою bar(можливо, включаючи файл barу поточному каталозі). Зауважте, що це не може поєднуватися з іншими формами глобалізації в межах одного сегменту шляху; у цьому випадку *оператори повертаються до звичного ефекту.

Зауважте, що між zshі bashтут є тонка різниця . Хоча bashбуде проходити м'які посилання на каталоги, zshне буде. Для цього вам потрібно використовувати глобус ***/в zsh.



-2
grep -R "somestring" | cut -d ":" -f 1

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