Полезность утилиты find

Утилита find занимает одно из почётнейших мест в моём инструментарии. Это обусловлено её удобством и многофункциональностью.

С помощью find можно найти файл с определённым именем:

$ find /tmp -type f -name 'note.txt'

/tmp/note.txt

Найти набор файлов с одним из расширений, -o тут заменяет логическое ИЛИ:

$ find src/ -type f -name '*.png' -o -name '*.svg'

src/logo.svg
src/logo.png

Если покопаться в man, есть огромное количество и других полезных аргументов и операторов. Один из них, -executable, позволит найти исполняемые файлы:

$ find Downloads/ -type f -executable

Downloads/grpcurl_1.8.9_linux_x86_64/grpcurl

Из альтернатив будет удобнее всего tree, но, скорее, для небольшого количества файлов:

$ tree -p grpcurl_1.8.9_linux_x86_64

[drwxr-xr-x]  grpcurl_1.8.9_linux_x86_64
├── [-rwxr-xr-x]  grpcurl
└── [-rw-r--r--]  LICENSE

1 directory, 2 files

Стандартные права в Linux на директорию установлены как 755 или drwxr-xr-x, а стандартные права на файлы как 644 или -rw-r--r--. В примере выше директория grpcurl_1.8.9_linux_x86_64 и файл LICENSE имеют как раз стандартные права. А вот grpcurl – исполняемый файл (программа).

А что, если нужно дать всем файлам в папке и её подпапках стандартные права вида 644 -rw-r--r--? И даже тут find с опцией -exec отлично поможет. Это опция позволяет передавать путь найденного файла другим программам, например, chmod:

$ find dir_from_ntfs/ -type f -exec chmod 644 {} \;

Вот и всё, теперь все файлы будут иметь установки доступа по-умолчанию. Конечно, есть возможность использовать и рекурсивный вариант chmod. Но, без find, эта задача имеет нетривиальное решение, не очевидное для начинающих:

$ chmod -R a=r,u+w,a+X dir_from_ntfs/

Исполняемые биты можно установить для отдельных файлов по мере необходимости. Но, если Вы очень хотите найти все .sh без прав исполнения, то find с оператором ! Вам точно поможет. !, как можно догадаться, будет означать логическое НЕ:

$ find dir_from_ntfs/ -type f -name '*.sh' ! -executable

dir_from_ntfs/my-super-cool-old-script.sh

Как найти все файлы-дубликаты, когда есть сложная структура файлов и папок? А именно, сравнить надо не 2 файла и не 2 папки? Утилита find в сочетании с md5sum, sort и uniq отлично подойдёт:

$ find . -type f -exec md5sum {} \; | sort | uniq -w 32 -D

e1bf26622aee5135236c71126e318f2d  ./some_cool_article_on_ddd.pdf
e1bf26622aee5135236c71126e318f2d  ./Vernon_2011_1.pdf

Находим контрольную сумму MD5 для каждого файла, сортируем результаты и находим дубликаты с помощью проверки первых 32 символов на уникальность. 32 символа – результат свёртки MD5, оставшаяся часть строки – путь к файлу, что позволяет просто идентифицировать копии и выбрать, что нужно удалить.

Журнал изменений

30 января 2024 г.: добавил примеры с chmod для установки прав по-умолчанию.

1 февраля 2024 г.: убрал излишнюю лирику, заменил пример chmod на более лаконичный.

24 февраля 2024 г.: заменил информацию про NTFS полезной командой поиска дубликатов.

Если Вы хотите обсудить содержание заметки, задать вопросы или предложить изменения, то со мной можно связаться в Telegram