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

Когда нужно очистить каталог от лишних файлов, сохранив только файлы определённых типов, 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 или аналогичным утилитам.

+1
0
+1
1
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *