× К оглавлению На главную Об авторе

   Дата и время публикации:

Назначение и практическое применение

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 могут быть переданы следующие буковки:

Дамп 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
Примечание. При этом опция -o используется для объединения не только исключаемых директорий в опции -path, но и масок имен абсолютных путей, как было показано в дампе 2.1.6

И вместо, полного списка поддиректорий /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?

3.5 Die.net. find(1) - Linux man page