Удалить все файлы, кроме некоторых, из каталога - PullRequest
203 голосов
/ 01 декабря 2010

Как использовать sudo rm -r, как удалить все файлы, кроме следующих:

textfile.txt
backup.tar.gz
script.php
database.sql
info.txt

Ответы [ 18 ]

209 голосов
/ 01 декабря 2010
find [path] -type f -not -name 'textfile.txt' -not -name 'backup.tar.gz' -delete

Если вы не укажете -type f, команда find также выведет список каталогов, которые вам могут не понадобиться.


Или более общее решение с использованием очень полезной комбинации find | xargs:

find [path] -type f -not -name 'EXPR' -print0 | xargs -0 rm --

например, удалите все не TXT-файлы в текущем каталоге:

find . -type f -not -name '*txt' -print0 | xargs -0 rm --

Комбинация print0 и -0 необходима, если есть пробелы в любомимена файлов, которые должны быть удалены.

148 голосов
/ 05 марта 2013
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)

Extglob (Extended Pattern Matching) должен быть включен в BASH (если он не включен):

shopt -s extglob
40 голосов
/ 01 декабря 2010

find . | grep -v "excluded files criteria" | xargs rm

При этом будут перечислены все файлы в текущем каталоге, затем перечислены все те, которые не соответствуют вашим критериям (остерегайтесь совпадения с именами каталогов), а затем удалены их.

Обновление : на основе ваших правок, если вы действительно хотите удалить все из текущего каталога, кроме файлов, которые вы перечислили, это можно использовать:

mkdir /tmp_backup && mv textfile.txt backup.tar.gz script.php database.sql info.txt /tmp_backup/ && rm -r && mv /tmp_backup/* . && rmdir /tmp_backup

Это создаст резервную копию каталога /tmp_backup (у вас есть права суперпользователя, верно?), Переместите файлы, которые вы перечислили в этот каталог, рекурсивно удалите все в текущем каталоге (вы знаете, что вы находитесь в правильном каталоге, не так ли?), Вернитесь в текущий каталогвсе из /tmp_backup и, наконец, удалите /tmp_backup.

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

Конечно, есть более элегантные способы сделать это, но этот довольно простой.

19 голосов
/ 04 мая 2012

Вы можете использовать переменную окружения GLOBIGNORE в Bash.

Предположим, что вы хотите удалить все файлы, кроме php и sql, тогда вы можете сделать следующее -

export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=

Установка GLOBIGNORE следующим образомигнорирует php и sql из подстановочных знаков, используемых как "ls *" или "rm *".Таким образом, использование «rm *» после установки переменной приведет к удалению только файлов txt и tar.gz.

18 голосов
/ 01 декабря 2010

Предполагая, что файлы с этими именами существуют в нескольких местах в дереве каталогов, и вы хотите сохранить их все:

find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete
16 голосов
/ 27 сентября 2017

Я предпочитаю использовать список подзапросов:

rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`

-v, --invert-match выбрать несовпадающие строки

\| Сепаратор

9 голосов
/ 22 декабря 2012

Так как никто не упомянул это:

  • скопируйте файлы, которые вы не хотите удалять, в безопасном месте
  • удалить все файлы
  • переместить скопированные файлы обратно на место
6 голосов
/ 10 апреля 2014

Немного опоздал для ОП, но, надеюсь, полезен для тех, кто попал сюда через google ...

Я нашел ответ @awi и комментарий -delete @Jamie Bullock действительно полезным.Простая утилита, позволяющая делать это в разных каталогах, игнорируя каждый раз разные имена / типы файлов с минимальным набором:

rm_except (или как вы хотите его назвать)

#!/bin/bash

ignore=""

for fignore in "$@"; do
  ignore=${ignore}"-not -name ${fignore} "
done

find . -type f $ignore -delete

например, дляудалите все, кроме текстовых файлов и foo.bar:

rm_except *.txt foo.bar 

Аналогично @mishunika, но без условия if.

6 голосов
/ 01 декабря 2010

Вы можете написать цикл for для этого ...%)

for x in *
do
        if [ "$x" != "exclude_criteria" ]
        then
                rm -f $x;
        fi
done;
5 голосов
/ 27 апреля 2016

Если вы используете zsh, который я настоятельно рекомендую.

rm -rf ^file/folder pattern to avoid

С extended_glob

setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)
...