# find и xargs

> find — утилита поиска файлов по имени, типу, размеру, времени изменения и другим признакам с выполнением действий над найденным; xargs превращает поток строк в аргументы команды.

Источник: https://llmdocs.ru/wiki/find-xargs/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Тип**: утилиты командной строки Unix
- **Появление**: PWB/Unix (1970-е)
- **Реализации**: GNU findutils, BSD find, BusyBox
- **Стандарт**: POSIX
- **Безопасная работа с именами**: -print0 и xargs -0
- **Современная альтернатива**: fd (Rust)
**find** — утилита Unix для поиска файлов и каталогов по множеству признаков: имени, типу, размеру, времени изменения, владельцу, [правам](https://llmdocs.ru/wiki/unix-permissions.md) — с возможностью сразу выполнить действие над каждым найденным файлом. **xargs** читает поток строк со стандартного ввода и подставляет их как аргументы в команду. Вместе они решают задачи вроде «удалить все логи старше 30 дней» или «найти все файлы `.py` и проверить их линтером».

Обе утилиты появились в 1970-х в PWB/Unix и описаны в стандарте POSIX;[2][3] в [Linux](https://llmdocs.ru/wiki/linux.md) используется реализация GNU findutils.

## find: основы

Синтаксис: `find [где искать] [условия] [действия]`.

```bash
find . -name "*.py"                       # по шаблону имени (с учётом регистра)
find . -iname "readme*"                   # без учёта регистра
find /var/log -type f -name "*.log"       # только файлы (d — каталоги, l — ссылки)
find . -type f -size +100M                # больше 100 МБ
find . -mtime -1                          # изменённые за последние сутки
find /tmp -type f -mtime +7 -delete       # удалить файлы старше 7 дней
find . -empty -type d                     # пустые каталоги
find . -user www-data ! -perm -u=r        # владелец www-data, но без права чтения
find . -name node_modules -prune -o -name "*.js" -print   # не заходить в node_modules
```

Шаблон имени нужно брать в кавычки: иначе оболочка раскроет `*.py` в текущем каталоге до запуска find.

### Условия

| Условие | Смысл |
|---|---|
| `-name`, `-iname`, `-path` | имя или путь по шаблону |
| `-regex` | путь по [регулярному выражению](https://llmdocs.ru/wiki/regex.md) |
| `-type f/d/l` | файл, каталог, символическая ссылка |
| `-size +N/-N` | размер больше или меньше (k, M, G) |
| `-mtime`, `-mmin`, `-newer` | время изменения в днях, минутах, новее файла |
| `-user`, `-group`, `-perm` | владелец, группа, права |
| `-maxdepth N` | глубина обхода |
| `!`, `-o`, `( )` | отрицание, «или», группировка (скобки экранируются) |

Условия, записанные подряд, объединяются через «и».[1]

### Действия

```bash
find . -name "*.tmp" -delete                    # удалить
find . -name "*.sh" -exec chmod +x {} \;        # команда для каждого файла отдельно
find . -name "*.py" -exec ruff check {} +       # одна команда для пачки файлов — быстрее
find . -type f -printf "%s %p\n" | sort -n | tail   # самые большие файлы (GNU find)
```

`{}` заменяется именем файла. Вариант `\;` запускает команду для каждого файла, `+` — передаёт сразу много файлов в одну команду, что на порядки быстрее для тысяч файлов.

## xargs

xargs читает строки и запускает команду, подставляя их в качестве аргументов, автоматически разбивая на пачки, чтобы не превысить ограничение длины командной строки.

```bash
cat urls.txt | xargs -n 1 curl -sO              # по одному аргументу на запуск
grep -rl "TODO" src/ | xargs wc -l              # число строк в файлах с TODO
find . -name "*.log" -print0 | xargs -0 gzip    # безопасно для имён с пробелами
find . -name "*.png" -print0 | xargs -0 -P 8 -n 10 optipng   # 8 процессов параллельно
echo "a b c" | xargs -I{} echo "элемент: {}"
```

- **`-0` вместе с `find -print0`** разделяет имена нулевым байтом. Без этого имена с пробелами, кавычками и переводами строк разбиваются неправильно — частая причина ошибок и даже удаления не тех файлов.
- **`-P N`** запускает до N процессов параллельно — простой способ задействовать все ядра. Для сложных случаев есть GNU Parallel.[5]
- **`-I{}`** подставляет строку в заданное место команды, **`-n N`** ограничивает число аргументов на запуск.
- **`-r`** (GNU) не запускает команду, если входных данных нет.

## Типичные рецепты

```bash
# найти и удалить старые резервные копии, сначала проверив список
find /backups -name "*.tar.gz" -mtime +30 -print
find /backups -name "*.tar.gz" -mtime +30 -delete

# что занимает место
find / -xdev -type f -size +1G 2>/dev/null

# поиск текста только в файлах определённого типа
find . -name "*.yaml" -print0 | xargs -0 grep -n "image:"

# переименовать расширение
find . -name "*.jpeg" -exec sh -c 'mv "$1" "${1%.jpeg}.jpg"' _ {} \;
```

Перед `-delete` или деструктивным `-exec` полезно сначала запустить команду с `-print` и посмотреть список — find выполнит действие над всем найденным без вопросов.

## fd — современная альтернатива

Утилита **fd**, написанная на [Rust](https://llmdocs.ru/wiki/rust.md), предлагает более простой синтаксис и разумные значения по умолчанию: ищет по подстроке или регулярному выражению, пропускает скрытые файлы и файлы из `.gitignore`, раскрашивает вывод и работает параллельно.[4]

```bash
fd "\.py$"                    # аналог find . -name "*.py", без .gitignore-файлов
fd -e log -x gzip             # найти .log и сжать каждый
fd -H config                  # включая скрытые файлы
```

Для поиска *содержимого* в файлах используют [grep](https://llmdocs.ru/wiki/grep.md) или ripgrep, для массовой правки текста — [sed и awk](https://llmdocs.ru/wiki/sed-awk.md).

## См. также

- [grep и регулярные выражения](https://llmdocs.ru/wiki/grep.md)
- [sed и awk](https://llmdocs.ru/wiki/sed-awk.md)
- [Конвейеры и перенаправление (pipes)](https://llmdocs.ru/wiki/pipes-redirection.md)
- [Файловая система Unix (FHS)](https://llmdocs.ru/wiki/fhs.md)
- [Shell и Bash](https://llmdocs.ru/wiki/shell-bash.md)

## Источники

1. [GNU Findutils manual](https://www.gnu.org/software/findutils/manual/html_mono/find.html)
2. [POSIX.1-2024 — find](https://pubs.opengroup.org/onlinepubs/9799919799/utilities/find.html)
3. [POSIX.1-2024 — xargs](https://pubs.opengroup.org/onlinepubs/9799919799/utilities/xargs.html)
4. [fd — a simple, fast and user-friendly alternative to find](https://github.com/sharkdp/fd)
5. [GNU Parallel](https://www.gnu.org/software/parallel/)
