Дата и время публикации:
Назначение и практическое применение
1. Назначение
Является утилитой поиска файлов и директорий путем рекурсивного обхода дерева файловой системы относительно пути последней [path...]. Синопсис вызова показан в дампе 1.1
Дампе 1.1
Find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
Применение необязательных опций [-H], [-L], [-P] и [-D debugopts], [-Olevel] в данном случае будет пропущено, т.к. первые три используются для обработки символических ссылок, а последние две отвечают за детализации выдачи диагностических сообщений и оптимизацию выполнения запросов.
Поэтому ниже будут рассматриваться опции [path…] и [expression], последняя интересна тем, что позволяет фильтровать поток самосознания, изрыгаемый find в процессе рекурсивного обхода, например, относительно директории, которая была указана в [path…]. При этом не нужно забывать, что в [path…] может быть указан и путь целевого поиска, например, в виде файла.
2. Практическое применение
2.1 Поиск всех регулярных файлов
относительно заданной директории поиска [path…] осуществляется, как показано в дампе 2.1.1
Дамп 2.1.1
$ find [path…] [-type f -name "*" -print ]
При этом группа опций [-type f -name "*" -print ] является той самой опцией [expression], которая отвечает за фильтрацию "потока самосознания". Так символ "*" в опции -name указывает на то, что выводятся все имена файлов.
В дампе 2.1.2 показан поиск поддиректорий относительно директории поиcка [path…]
Дамп 2.1.2
user@home:~$ find [path…] [-type d -name "*" -print]
При этом в указанной группе опций, изменила свой аргумент c "f" на "d" опция -type .
Кроме того, в опции -type могут быть переданы следующие буковки:
- буковки 'c' и 'b' позволят отфильтровать только файлы символьных и блочных файлов,
- буковка 'p' разыщет все файлы каналов PIPE,
- буковка 'l' символические ссылки; при этом, если стоит одна из пропущенной ранее опции [-L] [-P] [-H] или опция -follow , никого действия не произведет. Кроме того, для опции опции [-L] [-P] [-H] рекомендуется использовать -xtype , потому что опция -type не умеет читать файлы ссылок, которые содержат реальные пути, как показано в дампе 2.1.3
Дамп 2.1.3
user@home:~$ sudo find -L /dev -xtype l -wholename "\/dev\/fd\/*" -print /dev/fd/0 /dev/fd/1 /dev/fd/2 /dev/fd/3 /dev/fd/3/Документы/Programming/Posix/susv4-2018/idx/style.css /dev/fd/3/Документы/Programming/Posix/susv4-2018/help/style.css /dev/fd/3/Документы/Programming/Posix/susv4-2018/functions/style.css /dev/fd/3/Документы/Programming/Posix/susv4-2018/utilities/style.css /dev/fd/3/Документы/Programming/Posix/susv4-2018/basedefs/jscript /dev/fd/3/Документы/Programming/Posix/susv4-2018/basedefs/style.css /dev/fd/3/Документы/Programming/Posix/susv4-2018/basedefs/toc.html /dev/fd/3/Документы/Programming/Posix/susv4-2018/frontmatter/style.css /dev/fd/3/Документы/Programming/Posix/susv4-2018/xrat/style.css ...
Выполнение того же самого запроса для -type l показан в дампе 2.1.4
Дамп 2.1.4
user@home:~$ sudo find /dev -type l -wholename "\/dev\/fd\/*" -print user@home:~$
Из которого следует, что ничего найдено не было, потому что директория "/dev/fd/" является на самом деле ссылкой на директорию в псевдофайловой системы "/proc", как показано в дампе 2.1.5
Дамп 2.1.5
user@home:~$ $ ls -la /dev/fd lrwxrwxrwx 1 root root 13 фев 29 09:17 /dev/fd -> /proc/self/fd
Переданная в опции -wholename указанная маска "\/dev\/fd\/*" , как показано в дампе 2.1.3 ,заставляет find отфильтровывать найденные файлы, не имеющие в начале абсолютного пути "/dev/fd/...", что позволяет сокращать время поиска, отбирающего на себя всяких sed и grep .
Так в дампе 2.1.6 показано как отфильтровать в результате поиска те директории, которые в начале абсолютного пути имеют "/dev/input/..." или "/dev/disk/...".
Дамп 2.1.6
user@home:~$ find /dev -type d -wholename "dev\/input/*" -print -o -wholename "dev\/disk/*" -print /dev/input/by-path /dev/disk/by-id /dev/disk/by-path /dev/disk/by-partuuid /dev/disk/by-uuid
2.2 Поиск по ключевому словосочетанию содержимого файла
Например по "PATH_MAX", производится в выбранной директории, например "/usr/include", и расширению файла, например "*.h" , как показано в дампе 2.2.1
Дамп 2.2.1
user@home:~$ find /usr/include -type f -name "*.h" -print | xargs egrep -ne "PATH_MAX" /usr/include/libaudit.h:456:#define MAX_AUDIT_MESSAGE_LENGTH 8970 // PATH_MAX*2+CONTEXT_SIZE*2+11+256+1 /usr/include/selinux/selinux.h:454: * symlink. Resolved path must be a path of size PATH_MAX + 1 */ /usr/include/tic.h:119:#define MAX_ALIAS 32 /* smaller than POSIX minimum for PATH_MAX */ /usr/include/arm-linux-gnueabi/sys/param.h:47:#if !defined MAXPATHLEN && defined PATH_MAX /usr/include/arm-linux-gnueabi/sys/param.h:48:# define MAXPATHLEN PATH_MAX /usr/include/arm-linux-gnueabi/bits/posix1_lim.h:97:#define _POSIX_PATH_MAX 25 ...
Все совпадения во всех файлах, имеющие какие-либо расширения, как показано в дампе 2.2.2
Дамп 2.2.1
user@home:~$ find src -type f -name "*.*" -print | xargs egrep -ne "PATH_MAX"
Кроме заголовочных файлов, к выводу добавятся файлы исходного кода, например, написанные на языках С и Assmebler имеющие расширения после первой точки в имени файла.
2.3 Для исключения в поиске
например поддиректорий /dev/block, /dev/char и /dev/disk, относительно директории поиска /dev, необходимо использовать -prune с группировкой абсолютных путей директорий в скобках и опции -path, как показано в дампе 2.3.1
Дамп 2.3.1
user@home:~$ sudo find /dev/ -type d \( -path /dev/block -o -path /dev/char -o -path /dev/disk \) -prune -o -type d -name "*" -print | sort
И вместо, полного списка поддиректорий /dev/ , как показано в дампе 2.3.2
Дамп 2.3.2
/dev/disk /dev/disk/by-id /dev/disk/by-partuuid /dev/disk/by-path /dev/disk/by-uuid /dev/dri /dev/hugepages /dev/fd /dev/input /dev/input/by-path /dev/mapper /dev/mqueue /dev/net /dev/pts /dev/shm /dev/snd /dev/vfio
будет выведен укороченный, как показано в дампе 2.3.3
Дамп 2.3.3
/dev/ /dev/bsg /dev/dri /dev/hugepages /dev/fd /dev/input /dev/input/by-path /dev/mapper /dev/mqueue /dev/net /dev/pts /dev/shm /dev/snd /dev/vfio
Так же существует иной способ игнорирования поддиректорий с использованием -prune, как показано в дампе 2.3.4
Дамп 2.3.4
user@home:~$ find /dev -name "disk*" -prune -o -name "dr*" -prune -o -type d -print /dev /dev/fd /dev/snd /dev/vfio /dev/mapper /dev/net /dev/mqueue /dev/hugepages /dev/shm /dev/block /dev/char /dev/bsg /dev/pts /dev/input /dev/input/by-path ...
В результате будут исключены имена и пути директорий, которые начинаются на "disk*" и "dr*". При этом, в случае пропуска опции -print может получится не совсем приглядная картина, как показано в дампе 2.3.5
Дамп 2.3.5
user@home:~$ find /dev -name "disk*" -prune -o -name "dr*" -prune -o -type d /dev /dev/fd /dev/dri /dev/snd /dev/vfio /dev/mapper /dev/net /dev/mqueue /dev/hugepages /dev/shm /dev/disk /dev/block /dev/char /dev/bsg /dev/pts /dev/input /dev/input/by-path
Вместо, как показано в дампе 2.3.6, того что нужно было найти.
Дамп 2.3.6
user@home:~$ find /dev -name "disk*" -prune -o -name "dr*" -prune -o -type d -print /dev /dev/snd /dev/vfio /dev/mapper /dev/net /dev/mqueue /dev/hugepages /dev/shm /dev/block /dev/char /dev/bsg /dev/pts /dev/input /dev/input/by-path
Поэтому нужно не забывать, что ключевой опцией, кроме -prune, является и опция -print .
3. Библиография
3.1 Alvin Аlexander. A big collection of Unix/Linux 'find' command examples
3.2 TechMint.35 Practical Examples of Linux Find Command
3.3 Stackoverflow. How to exclude a directory in find command
3.4 Unix & Linux. Is it possible to exclude a directory from the find command?