Использование find - Удаление всех файлов/каталогов (в Linux), за исключением любого

Если мы хотим удалить все файлы и каталоги, которые мы используем, rm -rf *.

Но что, если я хочу, чтобы все файлы и каталоги были удалены при съемке, кроме одного конкретного файла?

Есть ли какая-нибудь команда для этого? rm -rf * дает простоту удаления при одном снимке, но удаляет даже мой любимый файл/каталог.

Заранее спасибо

Ответы

Ответ 1

find может быть очень хорошим другом:

$ ls
a/  b/  c/
$ find * -maxdepth 0 -name 'b' -prune -o -exec rm -rf '{}' ';'
$ ls
b/
$ 

Пояснение:

  • find * -maxdepth 0: выберите все, что выбрано *, не опуская ни одного каталога

  • -name 'b' -prune: не беспокойтесь (-prune) со всем, что соответствует условию -name 'b'

  • -o -exec rm -rf '{}' ';': вызов rm -rf для всего остального

Кстати, другой, возможно, более простой способ - переместить или переименовать ваш любимый каталог, чтобы он не мешал:
$ ls
a/  b/  c/
$ mv b .b
$ ls
a/  c/
$ rm -rf *
$ mv .b b
$ ls
b/

Ответ 2

Короткий ответ

ls | grep -v "z.txt" | xargs rm

Подробнее

Мыслительный процесс для указанной команды:

  • Список всех файлов (ls)
  • Список всех, кроме выбранного файла (grep -v "z.txt" )
  • Удалить перечисленные файлы (xargs rm)

Пример

Создайте 5 файлов, как показано ниже:

echo "a.txt b.txt c.txt d.txt z.txt" | xargs touch

Список всех файлов, кроме z.txt

ls|grep -v "z.txt"

a.txt
b.txt
c.txt
d.txt

Теперь мы можем удалить (rm) перечисленные файлы с помощью утилиты xargs:

ls|grep -v "z.txt"|xargs rm

Ответ 3

Вы можете ввести его прямо в командной строке или использовать эту комбинацию клавиш в script

files=`ls -l | grep -v "my_favorite_dir"`; for file in $files; do rm -rvf $file; done

P.S. Я предлагаю переключатель -i для rm, чтобы предотвратить деление важных данных.

P.P.S Вы можете написать небольшой script на основе этого решения и поместить его в /usr/bin (например, /usr/bin/rmf). Теперь вы можете использовать его как и обычное приложение:

rmf my_favorite_dir

script выглядит (только эскиз):

#!/bin/sh

if [[ -z $1 ]]; then
    files=`ls -l`
else
    files=`ls -l | grep -v $1`
fi;

for file in $files; do
    rm -rvi $file
done;

Ответ 4

По крайней мере, в zsh

rm -rf ^filename

может быть вариантом, если вы хотите сохранить только один файл.

Ответ 5

Если это всего лишь один файл, один простой способ - переместить этот файл в /tmp или что-то, rm -Rf в каталог, а затем переместить его обратно. Вы могли бы использовать это как простую команду.

Другой вариант - сделать find, а затем grep вне того, чего вы не хотите (используя -v или напрямую используя один из предикатов find), а затем rm остальные файлы.

Для одного файла я бы сделал первое. Для чего-то большего, я бы написал что-то обычное, похожее на то, что сказал thkala.

Ответ 6

В bash у вас есть оператор !() glob, который инвертирует согласованный шаблон. Чтобы удалить все, кроме файла my_file_name.txt, попробуйте следующее:

shopt -s extglob
rm -f !(my_file_name.txt)

См. эту статью для получения дополнительной информации: http://karper.wordpress.com/2010/11/17/deleting-all-files-in-a-directory-with-exceptions/

Ответ 7

Я не знаю такой программы, но я хотел ее в прошлом несколько раз. Основной синтаксис:

IFS='
' for f in $(except "*.c" "*.h" -- *); do
  printf '%s\n' "$f"
done

Программа, которую я имею в виду, имеет три режима:

  • точное соответствие (с опцией -e)
  • glob (по умолчанию, как показано в приведенном выше примере)
  • соответствие регулярному выражению (с опцией -r)

Требуется исключить шаблоны из командной строки, за которыми следует разделитель --, а затем имена файлов. В качестве альтернативы имена файлов могут быть считаны из stdin (если указан параметр -s), каждый из которых находится в строке.

Такая программа не должна быть сложной для записи, либо на C, либо на командном языке командной оболочки. И это делает хорошее упражнение для изучения основ Unix. Когда вы делаете это как программу оболочки, вы должны, конечно, следить за имена файлов, содержащие пробелы и другие специальные символы.

Ответ 8

Я вижу здесь много длинноволновых средств, которые работают, но с a/b/c/d/e/

 rm -rf *.* !(b*) 

это удаляет все, кроме каталога b/и его содержимого (если ваш файл находится в b/. Затем просто cd b/и

rm -rf *.* !(filename) 

чтобы удалить все остальное, но файл (с именем "filename" ), который вы хотите сохранить.

Ответ 9

mv subdir/preciousfile  ./
rm -rf subdir
mkdir subdir
mv preciousfile subdir/

Это выглядит утомительно, но довольно безопасно

  • избегает сложной логики
  • никогда не используйте rm -rf *, его результаты зависят от вашего текущего каталога (который может быть /; -)
  • никогда не используйте globbing *: его расширение ограничено ARGV_MAX.
  • позволяет вам проверять ошибку после каждой команды и, возможно, избегать катастрофы, вызванной следующей командой.
  • избегает неприятных проблем, вызванных пространством или NL в именах файлов.

Ответ 10

cd ..
ln trash/useful.file ./
rm -rf trash/*
mv useful.file trash/

Ответ 11

для этого вам нужно использовать регулярное выражение. Напишите регулярное выражение, которое выбирает все остальные файлы, кроме тех, которые вам нужны.