Использование 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
для этого вам нужно использовать регулярное выражение. Напишите регулярное выражение, которое выбирает все остальные файлы, кроме тех, которые вам нужны.