🧹 Удаление всех файлов в директории, кроме определённых расширений

Когда нужно очистить каталог от лишних файлов, сохранив только файлы определённых типов, Linux предлагает несколько способов сделать это быстро из терминала. Рассмотрим три метода: расширенные шаблоны (опция Bash extglob
), утилиту find и переменную Bash GLOBIGNORE – расскажем, как работает каждый, приведём пример команды и подскажем, когда какой способ удобнее использовать.
⚠️ Внимание: Будьте осторожны с командами удаления. Рекомендуется сначала протестировать их без удаления (например, через echo
или в безопасной директории) либо использовать опцию -i
для подтверждения каждого файла, чтобы не потерять нужные данные.
✨ Способ 1: Расширенные шаблоны Bash (extglob)
Этот метод использует встроенную возможность Bash для расширенного сопоставления шаблонов. С помощью специального шаблона !(pattern)
можно задать маску, которая означает «всё, что не соответствует указанному шаблону». Для начала необходимо включить поддержку extglob в текущем Shell:
shopt -s extglob # включаем расширенные шаблоны
Теперь можно применять шаблон !
при удалении. Например, чтобы удалить все файлы, кроме файлов с расширениями .zip
и .odt
в текущем каталоге:
rm -v !(*.zip|*.odt)
Эта команда удалит все файлы, имеющие другие расширения, кроме .zip и .odt. Выражение !(*.zip|*.odt)
означает «любое имя, которое не оканчивается на .zip
или .odt
». Флаг -v
в команде rm
включён для наглядности – утилита перечислит имена удалённых файлов в выводе.
После выполнения уборки не забудьте отключить режим extglob, если он больше не нужен:
shopt -u extglob # отключаем расширенные шаблоны
Когда использовать: Метод с extglob
удобен для быстрого удаления файлов в одном каталоге из интерактивного Bash. Он хорошо подходит, когда нужно исключить от удаления один-два известных типа файлов. Учтите, что предварительно придётся включить опцию extglob. Для рекурсивного удаления по подкаталогам или при очень большом числе файлов (когда шаблон может развернуться в слишком длинный список аргументов) лучше выбрать другой подход.
🔎 Способ 2: Утилита find
Вместо возможностей оболочки можно воспользоваться утилитой find
, которая ищет файлы по критериям и может выполнять над ними действия. Этот способ не требует специальных настроек Shell и подходит для более сложных случаев.
Чтобы удалить все файлы, кроме определённого типа, find
позволяет отфильтровать имена по шаблону. Используем параметр -not -name
(или ! -name
). Например, команда ниже удалит все файлы, кроме файлов с расширением .gz
(gzip-архивов) в текущем каталоге и во всех его подкаталогах:
find . -type f -not -name "*.gz" -delete
Аргумент -type f
ограничивает поиск только обычными файлами (исключая каталоги), а условие -not -name "*.gz"
отсекает файлы, чьи имена оканчиваются на .gz
. Опция -delete
приказывает сразу удалить найденные файлы.
Если нужно сохранить несколько разных расширений, можно указать несколько условий или объединить их логическим OR. К примеру, следующая команда удалит всё, кроме файлов с расширениями .gz
и .odt
:
find . -type f -not \( -name "*.gz" -o -name "*.odt" \) -delete
Здесь конструкция \( ... -o ... \)
группирует условия: -name "*.gz"
OR -name "*.odt"
. Обратные слэши перед скобками нужны, чтобы избежать их интерпретации самим Shell. Таким образом, удалению подвергнутся все файлы, не удовлетворяющие ни одному из шаблонов (то есть не .gz
и не .odt
).
Когда использовать: find
— мощный инструмент, особенно полезный для рекурсивного удаления в глубоко вложенных структурах каталогов. Его стоит выбирать, если нужно пройтись по подкаталогам автоматически или когда файлов очень много. Кроме того, find
не зависит от конкретной оболочки — команда сразу готова к работе в любом скрипте или терминале. При необходимости можно добавить параметр -maxdepth 1
, чтобы ограничить поиск только текущим каталогом (без рекурсии), или использовать связку с xargs
для дополнительного контроля (например, чтобы вывести список удаляемых файлов перед удалением через -print0 | xargs -0 -I{} rm -v {}
).
⚙️ Способ 3: Переменная GLOBIGNORE
(Bash)
Последний подход работает только в Bash и основан на встроенной переменной окружения GLOBIGNORE
, которая задаёт шаблоны файлов, игнорируемые при расширении глобальных масок (*
, ?
и т.д.). Проще говоря, мы можем заранее указать оболочке, какие имена исключить из рассмотрения, а затем удалить всё остальное обычной командой.
Сначала перейдите в нужный каталог:
cd /path/to/dir
Установите переменную GLOBIGNORE
, перечислив через двоеточие шаблоны файлов, которые нужно сохранить. Например, чтобы не трогать файлы с расширениями .odt
, .iso
и .txt
:
GLOBIGNORE=*.odt:*.iso:*.txt
Теперь выполните удаление всех файлов с помощью маски *
:
rm -v *
Команда rm -v *
удалит все файлы в текущем каталоге, кроме тех, что соответствуют шаблонам в переменной GLOBIGNORE
(то есть кроме файлов с расширениями .odt, .iso, .txt). Ключ -v
позволяет увидеть, какие именно файлы были удалены в процессе. После очистки каталога желательно сбросить значение переменной, чтобы вернуть обычное поведение shell:
unset GLOBIGNORE
Когда использовать: Приём с GLOBIGNORE
полезен, если вы работаете в Bash и хотите быстро удалить всё лишнее, указав список исключений «что оставить». Он удобен для одноразовой очистки текущего каталога без написания длинных команд. Однако помните, что этот способ специфичен для Bash и не будет работать в других оболочках. В скриптах или для массового удаления по системе его используют редко; в таких случаях надёжнее прибегнуть к find
или аналогичным утилитам.