Как я могу рекурсивно найти все файлы в текущей и вложенных папках на основе сопоставления с подстановочными знаками?

1889

Как я могу рекурсивно найти все файлы в текущей и вложенных папках на основе сопоставления с подстановочными знаками?

Джон
источник

Ответы:

2744

Используйте find для этого:

find . -name "foo*"

findнужна начальная точка, а .(точка) указывает на текущий каталог.

tux21b
источник
21
Я знаю, что это помечено как linux, но стоит упомянуть: путь требуется для других вариантов * nix, которые не являются linux. В Linux путь необязателен, если вы хотите использовать точку.
IslandCow
4
@Seatter "foo *" указывает find искать все файлы, которые начинаются с "foo". Это просто его пример. Вы можете использовать "gpio *", чтобы найти все файлы, имена которых начинаются с gpio, или просто "gpio1", чтобы найти все файлы с именем gpio1.
schumacher574
29
обратите внимание, что "foo *" находится в кавычках, поэтому оболочка не раскрывает его перед передачей для поиска. если бы вы только что это сделали find . foo*, то foo*были бы расширены и затем переданы, чтобы найти.
Гринч
33
Стоит подчеркнуть, что " "это очень необходимо для рекурсивного поиска.
WesternGun
3
Также полезно: если вы не хотите получать уведомления о каталогах, на которые у вас нет разрешения (или других ошибок), вы можете сделать этоfind . -name "foo*" 2>/dev/null
Jobbo
222

Поиск труб в grep часто более удобен; это дает вам полную силу регулярных выражений для произвольного сопоставления с подстановочными знаками.

Например, чтобы найти все файлы с нечувствительной к регистру строкой «foo» в имени файла:

~$ find . -print | grep -i foo
Пол Уипп
источник
58
findтакже имеют -iname, -regexи -iregexфлаги для регистронезависимого шаблона, регулярного выражения, и нечувствительных к регистру сопоставления регулярных выражений, так обжигающе к grepненужно.
iobender
7
Я не думаю, что нужно быть ненужным, но быть более удобным.
Элайджа Линн
1
Тем не менее, передача в grep -v может позволить вам использовать простые строки или регулярные выражения для удаления записей, которые вам не нужны.
door_number_three
3
@iobender - К сожалению, по опыту могу сказать, что не все системы поставляются с findкомандой, поддерживающей эти параметры. Иногда grepстановится единственным вариантом.
Мистер Лама
150

find найдет все файлы, которые соответствуют шаблону:

find . -name "*foo"

Однако, если вы хотите картинку:

tree -P "*foo"

Надеюсь это поможет!

IslandCow
источник
18
brew install treeдля пользователей Mac OSX без apt-getустановки
DeBraid
1
Протестировано на macOS Sierra, просто добавьте '--print' -> 'find. имя "* foo" - print '. superuser.com/questions/177289/searching-mac-through-terminal
Джон-Салиб,
2
sudo yum установить дерево -y для CentOS
Сантош Кумар Арджунан,
39
find -L . -name "foo*"

В некоторых случаях мне понадобился параметр -L для обработки символических ссылок на каталоги. По умолчанию символические ссылки игнорируются. В этих случаях это было довольно странно, так как я менял каталог на подкаталог и смотрел файл, соответствующий шаблону, но команда find не возвращала имя файла. Использование -L решает эту проблему. Варианты символьной ссылки для поиска: -P -L -H

toddcscar
источник
1
L переключатель очень полезен. Часто пользователь не имеет представления о нижележащих каталогах, являются ли они мягкими ссылками или обычными каталогами. Так что в случае сомнений всегда полезно использовать вариант L. По крайней мере, это всегда помогало мне.
Ритеш
2
Это был ответ для меня. Спасибо!
iedmrc
34

Если ваша оболочка поддерживает новую опцию globbing (может быть включена с помощью :)shopt -s globstar , вы можете использовать:

echo **/*foo*

найти любые файлы или папки рекурсивно. Это поддерживается Bash 4, zsh и аналогичными оболочками.


Лично я определил эту функцию оболочки:

f() { find . -name "*$1*"; }

Примечание. Над строкой можно вставить непосредственно в оболочку или добавить в ~/.bashrcфайл вашего пользователя .

Затем я могу искать любые файлы, набрав:

f some_name

В качестве альтернативы вы можете использовать fdутилиту с простым синтаксисом, например fd pattern.

kenorb
источник
1
Это просто входит в один уровень. Не возвращаться в подкаталоги для меня
Бронча
3
@Broncha Потому что вам нужно активировать расширенную глобализацию shopt -s globstarкомандой. Это поддерживается в Bash, Zsh и аналогичных оболочках.
Кенорб
bash-3.2$ shopt -s globstarдаетbash: shopt: globstar: invalid shell option name
drewish
@drewish Вам нужно обновить Bash до 4.x
kenorb
эхо * / * Фу менее быстр, чем найти
Йозеф Климук
32

fd

В случае, если findэто слишком медленно, попробуйте fdутилиту - простую и быструю альтернативу findнаписанному на Rust.

Синтаксис:

fd PATTERN

Демо-версия:

Домашняя страница: https://github.com/sharkdp/fd

kenorb
источник
17
Впервые я увидел подарок на SO почти за 9 лет. Хорошая работа!
Джошуа Пинтер
1
Эти результаты производительности выглядят очень многообещающе. Вы могли бы рассмотреть возможность добавления fd к домашнему
пиву
не по теме: какой инструмент вы использовали для создания SVG-файла для демо?
Апродан
2
@aprodan Демонстрационное изображение было скопировано с GitHub, но я полагаю, что они используют asciinema, а затем преобразованы в формат GIF, но я не уверен.
Кенорб
1
На самом деле это формат SVG, поэтому, вероятно, asciicast2vectorможно использовать.
kenorb
27
find <directory_path>  -type f -name "<wildcard-match>"

В подстановочном знаке вы можете указать строку, которую хотите сопоставить, например * .c (для всех файлов c)

XYZ_Linux
источник
1
Ваш ответ является первым наиболее правильным здесь, поскольку он ищет только файлы, как указано. Другие, не указывающие тип, будут возвращать каталоги.
wilsotc
если вы хотите найти каталог "-type f", вы можете изменить его на "
-type
11

Ты можешь использовать:

# find . -type f  -name 'text_for_search'

Если вы хотите использовать REGX, используйте -iname

# find . -type f  -iname 'text_for_search'
user8848899
источник
9

Следующая команда выведет список всех файлов с точным именем «шаблон» (например) в текущей и ее подпапках.

find ./ -name "pattern"

Anshul
источник
8

Способ поиска рекурсивного файла по умолчанию, доступный в большинстве случаев,

find . -name "filepattern"

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

man find

или если справочные страницы недоступны в вашей системе

find --help

Однако, есть более современные и более быстрые инструменты, чем поиск, которые пересекают всю вашу файловую систему и индексируют ваши файлы, одним из таких распространенных инструментов является locate или slocate / mlocate, вы должны проверить руководство вашей ОС, как его установить, и как только Для установки необходимо запустить базу данных, если сценарий установки не делает этого за вас, это можно сделать вручную, набрав

sudo updatedb

И, чтобы использовать его для поиска определенного типа файла

locate filename

Или, чтобы найти имя файла или шаблон из текущего каталога, вы можете набрать:

 pwd | xargs -n 1 -I {} locate "filepattern"

Он просмотрит свою базу данных файлов и быстро распечатает имена путей, которые соответствуют введенному вами шаблону. Чтобы увидеть полный список параметров поиска, введите: locate --helpилиman locate

Кроме того, вы можете настроить locate для обновления его базы данных в запланированное время с помощью задания cron, поэтому пример cron, который обновляет db в 1:00, будет выглядеть так:

0 1 * * * updatedb

Эти задания cron должны быть настроены пользователем root, так как updatedb требует привилегий root для обхода всей файловой системы.

Александар Павич
источник
7

для поиска файлов
find / -xdev -name settings.xml -> весь компьютер
find ./ -xdev -name settings.xml -> текущий каталог и его подкаталог

для файлов с типом расширения

find . -type f -name "*.iso"
Alberto
источник
6

Я удивлен, увидев, что locate не используется интенсивно, когда мы должны идти рекурсивно.

Сначала я должен найти «$ PWD», чтобы получить список файлов в текущей интересующей папке, а затем запустить greps для них, как мне будет угодно.

locate "$PWD" | grep -P <pattern>

Конечно, это предполагает, что updatedb выполнен, и индекс периодически обновляется. Это гораздо более быстрый способ найти файлы, чем запустить поиск и попросить его перейти по дереву. Упомяну это для полноты. Ничего против использования find, если дерево не очень тяжелое.

melchi
источник
locate "$PWD*.mp4" Просто чтобы напомнить, что вы можете пропуститьgrep
Джеффри Кейв
5

Команда ниже помогает искать любые файлы

1) Независимо от случая
2) Результат Исключение папок без разрешения
3) Поиск в корне или по нужному пути. Изменить / с пути, который вы предпочитаете.

Синтаксис:
find -iname '' 2> & 1 | Пример grep -v "Отказано в доступе"


find / -iname 'C * .xml' 2> & 1 | grep -v "В доступе отказано"

find / -iname '*C*.xml'   2>&1 | grep -v "Permission denied"
MukeshKoshyM
источник
1
с какой стати вы используете grep для этого? Просто перенаправьте stderr на find / -iname '*C*.xml' 2>/dev/null
ноль
3

Если вы хотите найти специальный файл с подстановочными знаками, вы можете использовать следующий код:

find . -type f -name "*.conf"

Предположим, вы хотите искать все файлы .conf здесь:

.означает, что поиск начался отсюда (текущее место)
-typeозначает тип элемента поиска, который здесь является файлом (f).
-nameозначает, что вы хотите искать файлы с именами * .conf .

Реза Харасани
источник
3

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

find . -name "*.wanted" | xargs wc -l
Джей Ян
источник
2

использование

find path/to/dir -name "*.ext1" -o -name "*.ext2"

объяснение

  1. Первый параметр - это каталог, который вы хотите найти.
  2. По умолчанию find рекурсия.
  3. -oОзначает -or. Так что выше означает поиск этого шаблона или этого. Если у вас есть только один шаблон, то нет необходимости-o .
  4. Кавычки вокруг шаблона подстановки обязательны.
Шиталь шах
источник