найти (Unix)
Эта статья нуждается в дополнительных цитатах для проверки . ( июнь 2016 г. ) |
Оригинальный автор(ы) | Дик Хейт |
---|---|
Разработчик(и) | AT&T Bell Laboratories |
Операционная система | Unix , Unix-подобные , Plan 9 , IBM i |
Платформа | Кросс-платформенный |
Тип | Команда |
В -подобных операционных системах Unix find
— это утилита командной строки , которая находит файлы на основе некоторых критериев, заданных пользователем , и либо печатает путь к каждому совпадающему объекту, либо, если запрашивается другое действие, выполняет это действие над каждым совпадающим объектом.
Он инициирует поиск из желаемого начального местоположения, а затем рекурсивно обходит узлы (каталоги) иерархической структуры (обычно дерева ). find может просматривать и искать в различных файловых системах разделов, принадлежащих одному или нескольким устройствам хранения, смонтированным в исходном каталоге. [1]
Возможные критерии поиска включают шаблон для сопоставления с именем файла или временной диапазон для сопоставления со временем модификации или временем доступа к файлу. По умолчанию, find
возвращает список всех файлов ниже текущего рабочего каталога , хотя пользователи могут ограничить поиск любым желаемым максимальным количеством уровней в начальном каталоге.
Соответствующие locate
программы используют базу данных индексированных файлов, полученных с помощью find
(обновляется через регулярные промежутки времени, обычно cron
задание), чтобы обеспечить более быстрый метод поиска файлов по имени во всей файловой системе.
История [ править ]
find
появился в версии 5 Unix как часть проекта Programmer's Workbench и был написан Диком Хейтом вместе с cpio , [2] которые были разработаны для совместного использования. [3]
ГНУ find
реализация была первоначально написана Эриком Декером. Позже он был улучшен Дэвидом Маккензи, Джеем Плеттом и Тимом Вудом. [4]
The Команда find также была перенесена в операционную систему IBM i . [5]
Найти синтаксис [ править ]
$ find [-H|-L] path... [operand_expression...]
Эти два параметра управляют тем, как find
команда должна обрабатывать символические ссылки. Поведение по умолчанию — никогда не переходить по символическим ссылкам. -L
флаг приведет к find
команда для перехода по символическим ссылкам. -H
flag будет следовать только по символическим ссылкам при обработке аргументов командной строки. Эти флаги указаны в стандарте POSIX для find
. [6] Распространенным расширением является -P
флаг для явного отключения перехода по символическим ссылкам. [7] [8]
Выражению должен предшествовать хотя бы один путь. find
способен интерпретировать подстановочные знаки внутри себя, и команды необходимо заключать в кавычки, чтобы контролировать подстановку команд оболочки .
Элементы выражения разделяются границей аргумента командной строки , обычно представленной пробелами в синтаксисе оболочки. Они оцениваются слева направо. Они могут содержать логические элементы, такие как AND ( -and
или -a
) и ИЛИ ( -or
или -o
), а также предикаты (фильтры и действия).
ГНУ find
имеет большое количество дополнительных функций, не предусмотренных POSIX.
Предикаты [ править ]
Обычно используемые праймериз включают в себя:
-name pattern
: проверяет, соответствует ли имя файла заданному шаблону оболочки.-type type
: проверяет, принадлежит ли файл заданному типу. Принимаемые типы файлов Unix включают:b
: блочное устройство (с буферизацией) ;c
: символьное устройство (без буферизации) ;d
: каталог ;f
: обычный файл ;l
: символическая ссылка ;p
: именованный канал ;s
: розетка ;D
: дверь .
-print
: всегда возвращает истину; печатает имя текущего файла плюс новую строку в стандартный вывод .-print0
: всегда возвращает истину; выводит имя текущего файла плюс нулевой символ в стандартный вывод . Не требуется POSIX.-exec program [arguments...] ;
: запускает программу с заданными аргументами и возвращает true, если ее статус выхода равен 0, в противном случае — false. Если программа или аргумент равен {} , он будет заменен текущим путем (если программа равна {} ,find
попытается запустить текущий путь как исполняемый файл). POSIX не определяет, что должно произойти, если несколько {} указано заменяются . В большинстве реализаций все {} текущим путем, но это не стандартное поведение.-exec program [arguments...] {} +
: всегда возвращает истину; запустите программу с заданными аргументами, за которыми следует как можно больше путей (несколько команд будут запущены, если будет превышен максимальный размер командной строки, как для xargs ). [6]-ok program [arguments...] ;
: для каждого пути запрашивается подтверждение пользователя; если пользователь подтверждает (обычно вводя y или yes ), он ведет себя как-exec program [arguments...] ;
, в противном случае команда не запускается для текущего пути и возвращается false.
Если в выражении не используется ни один из -print0
, -print
, -exec
, или -ok
, найти настройки по умолчанию для выполнения -print
если условия проверяются как истинные.
Операторы [ править ]
Операторы можно использовать для улучшения выражений команды поиска. Операторы перечислены в порядке убывания приоритета:
( expr )
: приоритет приоритета;! expr
: true, если выражение ложно;expr1 expr2
(илиexpr1 -a expr2
: И.expr2
не оценивается, еслиexpr1
является ложным;expr1 -o expr2
: ИЛИ. выражение2 не оценивается, еслиexpr1
это правда.
$ find . -name 'fileA_*' -o -name 'fileB_*'
Эта команда ищет в текущем дереве рабочих каталогов файлы, имена которых начинаются с fileA_
или fileB_
. Мы цитируем fileA_*
чтобы оболочка не расширяла его.
$ find . -name 'foo.cpp' '!' -path '.svn'
Эта команда ищет в текущем дереве рабочих каталогов, за исключением дерева подкаталогов «.svn», файлы с именем «foo.cpp». Мы цитируем !
чтобы он не интерпретировался оболочкой как символ замены истории.
от вывода бесконечного Защита POSIX
Реальные файловые системы часто содержат зацикленные структуры, созданные с помощью жестких или программных ссылок . Стандарт POSIX требует, чтобы
The
find
утилита должна обнаруживать бесконечные циклы; то есть вход в ранее посещенный каталог, который является предком последнего встреченного файла. Когда он обнаруживает бесконечность петля,find
должен записать диагностическое сообщение в стандартную ошибку и либо восстановить свое положение в иерархии или прекратить.
Примеры [ править ]
Из текущего рабочего каталога [ править ]
$ find . -name 'my*'
При этом в текущем дереве рабочих каталогов выполняется поиск файлов, имена которых начинаются с моего . Одинарные кавычки позволяют избежать расширения оболочки — без них оболочка заменила бы my* списком файлов, имена которых начинаются с my, в текущем рабочем каталоге. В более новых версиях программы каталог может быть опущен, и под ним будет подразумеваться текущий рабочий каталог.
Только обычные файлы [ править ]
$ find . -name 'my*' -type f
Это ограничивает результаты вышеуказанного поиска только обычными файлами, поэтому исключая каталоги, специальные файлы, символические ссылки и т. д. my* заключен в одинарные кавычки (апострофы), так как в противном случае оболочка заменит его списком файлов в текущем рабочий каталог, начинающийся с моего …
Команды [ править ]
В предыдущих примерах были созданы списки результатов, поскольку по умолчанию find
выполняет -print
действие. (Обратите внимание, что ранние версии find
у команды вообще не было действия по умолчанию; поэтому результирующий список файлов будет отброшен, к недоумению пользователей.)
$ find . -name 'my*' -type f -ls
При этом печатается расширенная информация о файле.
Искать во всех каталогах [ править ]
$ find / -name myfile -type f -print
При этом в каждом каталоге выполняется поиск обычного файла с именем myfile и выводится его на экран. Обычно искать файлы таким способом не рекомендуется. Это может занять значительное время, поэтому лучше указать каталог поточнее. Некоторые операционные системы могут монтировать динамические файловые системы, несовместимые с find
. Более сложные имена файлов, включающие специальные символы оболочки, возможно, придется заключать в одинарные кавычки.
Искать во всех подкаталогах, кроме одного [ править ]
$ find / -path excluded_path -prune -o -type f -name myfile -print
При этом выполняется поиск во всех каталогах, за исключением дерева подкаталогов исключенный_путь (полный путь, включая начальный /), который отсекается -prune
действие для обычного файла с именем myfile .
Укажите каталог [ править ]
$ find /home/weedly -name myfile -type f -print
При этом в дереве каталогов /home/weedly будут найдены обычные файлы с именем myfile . Вы всегда должны указывать каталог до самого глубокого уровня, который вы можете запомнить.
Поиск в нескольких каталогах [ править ]
$ find local /tmp -name mydir -type d -print
При этом выполняется поиск в дереве локальных подкаталогов текущего рабочего каталога и в дереве каталогов /tmp каталогов с именем mydir .
Игнорировать ошибки [ править ]
Если вы делаете это от имени пользователя, отличного от root, вы можете игнорировать ошибки отказа в доступе (и любые другие). Поскольку ошибки выводятся в stderr , их можно подавить, перенаправив вывод на /dev/null. В следующем примере показано, как это сделать в оболочке bash:
$ find / -name myfile -type f -print 2> /dev/null
Если вы являетесь пользователем csh или tcsh , вы не можете перенаправить stderr без перенаправления stdout . Вы можете использовать sh для запуска find
команда, чтобы обойти это:
$ sh -c "find / -name myfile -type f -print 2> /dev/null"
Альтернативный метод при использовании csh или tcsh — передать выходные данные stdout и stderr в команду grep . В этом примере показано, как подавить строки, содержащие ошибки отказа в разрешении.
$ find . -name myfile |& grep -v 'Permission denied'
Найдите любой файл с разными именами [ править ]
$ find . \( -name '*jsp' -o -name '*java' \) -type f -ls
The -ls
Оператор выводит расширенную информацию, а пример находит любой обычный файл, имя которого заканчивается на «jsp» или «java». Обратите внимание, что скобки обязательны. Во многих оболочках круглые скобки необходимо экранировать обратной косой чертой ( \(
и \)
), чтобы они не интерпретировались как специальные символы оболочки. -ls
оператор доступен не во всех версиях find
.
Выполнить действие [ править ]
$ find /var/ftp/mp3 -name '*.mp3' -type f -exec chmod 644 {} \;
Эта команда изменяет права доступа для всех обычных файлов, имена которых заканчиваются на .mp3, в дереве каталогов /var/ftp/mp3 . Действие осуществляется указанием оператора -exec chmod 644 {} \;
в команде. Для каждого обычного файла, имя которого заканчивается на .mp3
, команда chmod 644 {}
выполняется замена {}
с именем файла. Точка с запятой (обратная косая черта, чтобы оболочка не интерпретировала ее как разделитель команд) указывает на конец команды. Разрешение 644
, обычно изображается как rw-r--r--
, дает владельцу файла полное разрешение на чтение и запись файла, в то время как другие пользователи имеют доступ только для чтения. В некоторых оболочках {}
необходимо цитировать. Следующее " ;
" обычно цитируется с начала " \
", но с тем же успехом его можно было бы заключить в одинарные кавычки.
Обратите внимание, что сама команда не должна заключаться в кавычки; в противном случае вы получите сообщения об ошибках, например
find: echo "mv ./3bfn rel071204": No such file or directory
это означает, что find
пытается запустить файл с именем ' echo "mv ./3bfn rel071204"
' и терпит неудачу.
Если вы будете выполнять множество результатов, более эффективно использовать вариант основного exec, который собирает имена файлов до ARG_MAX , а затем выполняет COMMAND со списком имен файлов.
$ find . -exec COMMAND {} +
Это гарантирует, что имена файлов с пробелами передаются исполняемой программе. COMMAND
не разделяясь оболочкой.
Удаление файлов и каталогов [ править ]
The -delete
action — это расширение GNU, и его использование включает -depth
. Итак, если вы тестируете команду поиска с помощью -print
вместо -delete
чтобы выяснить, что произойдет, прежде чем приступить к этому, вам нужно использовать -depth -print
.
Удалите пустые файлы и напечатайте имена (обратите внимание, что -empty
это уникальное расширение от GNU. find
это может быть доступно не во всех find
реализации):
$ find . -empty -delete -print
Удалить пустые обычные файлы:
$ find . -type f -empty -delete
Удалить пустые каталоги:
$ find . -type d -empty -delete
Удалите пустые файлы с именем «плохие»:
$ find . -name bad -empty -delete
Предупреждение. — -delete
действие следует использовать с такими условиями, как -empty
или -name
:
$ find . -delete # this deletes all in .
Поиск строки [ править ]
Эта команда выполнит поиск во всех файлах дерева каталогов /tmp строки:
$ find /tmp -type f -exec grep 'search string' /dev/null '{}' \+
The /dev/null
Аргумент используется для отображения имени файла перед найденным текстом. Без него печатается только найденный текст. (В качестве альтернативы некоторые версии grep поддерживают -H флаг, который заставляет печатать имя файла.)
ГНУ grep
может использоваться отдельно для выполнения этой задачи:
$ grep -r 'search string' /tmp
Пример поиска «LOG» в дереве домашних каталогов jsmith:
$ find ~jsmith -exec grep LOG '{}' /dev/null \; -print
/home/jsmith/scripts/errpt.sh:cp $LOG $FIXEDLOGNAME
/home/jsmith/scripts/errpt.sh:cat $LOG
/home/jsmith/scripts/title:USER=$LOGNAME
Пример поиска строки «ERROR» во всех XML-файлах текущего дерева рабочих каталогов:
$ find . -name "*.xml" -exec grep "ERROR" /dev/null '{}' \+
Двойные кавычки (" "), окружающие строку поиска, и одинарные кавычки (' '), окружающие фигурные скобки, в этом примере не являются обязательными, но необходимы для того, чтобы в строке можно было использовать пробелы и некоторые другие специальные символы. Обратите внимание, что для более сложного текста (особенно в большинстве популярных оболочек, произошедших от `sh` и `csh`), одинарные кавычки часто являются более простым выбором, поскольку двойные кавычки не препятствуют любой специальной интерпретации . Заключение в кавычки имен файлов с английскими сокращениями показывает, насколько это может быть довольно сложно, поскольку строку с апострофом легче защитить двойными кавычками:
$ find . -name "file-containing-can't" -exec grep "can't" '{}' \; -print
Поиск всех файлов, принадлежащих пользователю [ править ]
$ find . -user <userid>
Поиск в режиме без учета регистра [ править ]
Обратите внимание, что -iname
отсутствует в стандарте и может поддерживаться не всеми реализациями.
$ find . -iname 'MyFile*'
Если -iname
Switch не поддерживается в вашей системе, то могут быть возможны методы обхода, такие как:
$ find . -name '[mM][yY][fF][iI][lL][eE]*'
Поиск файлов по размеру [ править ]
Поиск файлов размером от 100 до 500 килобайт:
$ find . -size +100k -a -size -500k
Поиск пустых файлов:
$ find . -size 0k
Поиск непустых файлов:
$ find . ! -size 0k
Поиск файлов по имени и размеру [ править ]
$ find /usr/src ! \( -name '*,v' -o -name '.*,v' \) '{}' \; -print
Эта команда выполнит поиск в дереве каталогов /usr/src. Все файлы вида '*, v' и '.*,v' исключены. Важные аргументы, на которые следует обратить внимание, находятся во всплывающей подсказке , которая отображается при наведении курсора мыши.
for file in $(find /opt \( -name error_log -o -name 'access_log' -o -name 'ssl_engine_log' -o -name 'rewrite_log' -o -name 'catalina.out' \) -size +300000k -a -size -5000000k); do
cat /dev/null > $file
done
Юниты должны быть одними из [bckw] , «b» означает блоки по 512 байт, «c» означает байт, «k» означает килобайты, а «w» означает 2-байтовые слова. Размер не учитывает косвенные блоки, но учитывает блоки в разреженных файлах, которые фактически не выделены.
Поиск файлов по времени [ править ]
Диапазоны дат можно использовать, например, для отображения списка файлов, измененных с момента резервного копирования.
-mtime
: время модификации-ctime
: время смены индексного дескриптора-atime
: время доступа
Файлы были изменены относительное количество дней назад:
- +[число] = По крайней мере, столько дней назад.
- -[число] = Меньше, чем много дней назад.
- [число] = Ровно столько дней назад.
- При желании добавьте
-daystart
для измерения времени от начала дня (0 часов), а не за последние 24 часа.
Пример поиска всех текстовых файлов в папке документов, измененных за неделю (то есть 7 дней):
$ find ~/Documents/ -iname "*.txt" -mtime -7
Файлы, измененные до или после абсолютной даты и времени:
-newermt YYYY-MM-DD
: Последнее изменение после даты-not -newermt YYYY-MM-DD
: Последнее изменение до даты
Пример поиска всех текстовых файлов, последний раз редактированных в феврале 2017 года:
$ find ~/Documents/ -iname "*.txt" -newermt 2017-02-01 -not -newermt 2017-03-01
-newer [file]
: файл был изменен позже указанного.-cnewer
: То же самое со временем смены индексного дескриптора.-anewer
: То же самое со временем доступа.- Также можно добавить с
-not
для обратных результатов или диапазона.
Перечислите все текстовые файлы, отредактированные позднее «document.txt»:
$ find ~/Documents/ -iname "*.txt" -newer document.txt
Сопутствующие утилиты [ править ]
locate
— это инструмент поиска Unix, который ищет в заранее созданной базе данных файлов вместо деревьев каталогов файловой системы. Это быстрее, чемfind
но менее точный, поскольку база данных может быть устаревшей.grep
— это утилита командной строки для поиска в наборах данных в виде простого текста строк, соответствующих регулярному выражению, и по умолчанию выдает отчет о совпадении строк в стандартном выводе .tree
— это утилита командной строки, которая рекурсивно перечисляет файлы, найденные в дереве каталогов, делая отступы в именах файлов в соответствии с их положением в файловой иерархии.- GNU Find Utilities (также известный как findutils) — это пакет GNU , содержащий реализации инструментов.
find
иxargs
. - BusyBox — это утилита, которая содержит несколько урезанных инструментов Unix в одном исполняемом файле, предназначенная для встраиваемых операционных систем с очень ограниченными ресурсами. Он также предоставляет версию
find
. dir
имеет параметр /s, который рекурсивно ищет файлы или каталоги.- Plan 9 от Bell Labs использует для замены две утилиты
find
: аwalk
который только ходит по дереву и печатает имена иsor
который фильтрует (например, grep) только путем оценки выражений в форме сценария оболочки. Через каналы можно использовать произвольные фильтры. Команды не являются частью Plan 9 из User Space , поэтому у Бенджамина Баренблата из Google есть портированная версия для систем POSIX, доступная через GitHub. [9] fd
это простая альтернативаfind
написан на языке программирования Rust . [10]
См. также [ править ]
- mdfind — аналогичная утилита, использующая метаданные для macOS и Darwin.
- Список команд Unix
- Список команд DOS
- Фильтр (функция высшего порядка)
- find (Windows) — команда DOS и Windows, которая сильно отличается от Unix.
find
- forfiles — команда Windows, которая находит файлы по атрибуту, аналогично Unix.
find
- grep — команда Unix, которая находит текст, соответствующий шаблону, аналогично Windows.
find
Ссылки [ править ]
- ^ «find(1) — страница руководства Linux» . man7.org . Проверено 19 ноября 2019 г.
- ^ Макилрой, доктор медицины (1987). Читатель Research Unix: аннотированные выдержки из Руководства программиста, 1971–1986 (PDF) (Технический отчет). CSTR. Лаборатории Белла. 139.
- ^ "лиархив/лиархив" . Гитхаб . Проверено 4 октября 2015 г.
- ^ Поиск файлов
- ^ «Программирование Qshell в IBM System i версии 7.2» (PDF) . ИБМ . Проверено 05 сентября 2020 г.
- ^ Jump up to: Перейти обратно: а б Единая спецификация UNIX , версия 4 от The Open Group : найти файлы — Справочник по оболочке и утилитам,
- ^ FreeBSD по основным командам Руководство –
- ^ Linux пользователя Руководство – Пользовательские команды –
- ^ "google/walk: запланируйте 9 утилит в стиле для замены find(1)" . Гитхаб . Проверено 30 марта 2020 г.
- ^ Питер, Дэвид (30 марта 2020 г.). «sharkdp/fd: простая, быстрая и удобная альтернатива функции «найти» » . Гитхаб .
Внешние ссылки [ править ]
