Rm все файлы, кроме некоторых
При использовании sudo rm -r
, как я могу удалить все файлы, за исключением следующего:
textfile.txt
backup.tar.gz
script.php
database.sql
info.txt
Ответы
Ответ 1
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
необходима, если в любом из файлов, которые должны быть удалены, есть пробелы.
Ответ 2
rm !(textfile.txt|backup.tar.gz|script.php|database.sql|info.txt)
Должна быть включена опция extglob (Extended Pattern Matching) в BASH (если она не включена):
shopt -s extglob
Ответ 3
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
(у вас есть права на root, правильно?), переместите файлы, которые вы указали в этот каталог, удалите рекурсивно все в текущем каталоге (вы знаете, что находитесь в правильном каталоге, вы?), вернитесь к текущему каталогу все из /tmp_backup
и, наконец, удалите /tmp_backup
.
Я выбираю, чтобы каталог резервного копирования был в корневом каталоге, потому что если вы пытаетесь удалить все рекурсивно из корня, ваша система будет иметь большие проблемы.
Конечно, есть более элегантные способы сделать это, но это довольно просто.
Ответ 4
Предполагая, что файлы с этими именами существуют в нескольких местах в дереве каталогов, и вы хотите сохранить их все:
find . -type f ! -regex ".*/\(textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt\)" -delete
Ответ 5
Вы можете использовать переменную среды GLOBIGNORE в Bash.
Предположим, вы хотите удалить все файлы, кроме php и sql, тогда вы можете сделать следующее -
export GLOBIGNORE=*.php:*.sql
rm *
export GLOBIGNORE=
Установка GLOBIGNORE, как это, игнорирует php и sql из подстановочных знаков, используемых как "ls *" или "rm *". Таким образом, с помощью "rm *" после установки переменной удаляется только файл txt и tar.gz.
Ответ 6
Так как никто не упоминал об этом:
- скопируйте файлы, которые вы не хотите удалять в безопасном месте.
- удалить все файлы
- переместите скопированные файлы на место
Ответ 7
Немного поздно для OP, но, надеюсь, полезно для тех, кто получает здесь намного позже google...
Я нашел ответ от @awi и прокомментировал -delete by @Jamie Bullock действительно полезный. Простая утилита, поэтому вы можете сделать это в разных каталогах, игнорируя разные имена/типы файлов каждый раз при минимальном наборе текста:
rm_except (или все, что вы хотите назвать)
#!/bin/bash
ignore=""
for fignore in "[email protected]"; do
ignore=${ignore}"-not -name ${fignore} "
done
find . -type f $ignore -delete
например. для удаления всего, кроме текстовых файлов и foo.bar:
rm_except *.txt foo.bar
Аналогично @mishunika, но без предложения if.
Ответ 8
Вы можете написать цикл for для этого...%)
for x in *
do
if [ "$x" != "exclude_criteria" ]
then
rm -f $x;
fi
done;
Ответ 9
Попытка работать с:
rm -r !(Applications|"Virtualbox VMs"|Downloads|Documents|Desktop|Public)
но имена с пробелами (как всегда) жесткие. Пробовал также Virtualbox\ VMs
вместо кавычек. Он всегда удаляет этот каталог (Virtualbox VMs
).
Ответ 10
Я предпочитаю использовать список подпрограмм:
rm -r `ls | grep -v "textfile.txt\|backup.tar.gz\|script.php\|database.sql\|info.txt"`
-v, -invert-match выбирает несогласованные строки
\|
Сепаратор
Ответ 11
Если вы используете zsh
, который я настоятельно рекомендую.
rm -rf ^file/folder pattern to avoid
С extended_glob
setopt extended_glob
rm -- ^*.txt
rm -- ^*.(sql|txt)
Ответ 12
Просто:
rm $(ls -I "*.txt" ) #Deletes file type except *.txt
Или:
rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes file types except *.txt & *.pdf
Ответ 13
Вместо того, чтобы перейти к прямой команде, переместите необходимые файлы в temp dir за пределами текущего каталога. Затем удалите все файлы с помощью rm *
или rm -r *
.
Затем переместите нужные файлы в текущий каталог.
Ответ 14
Это похоже на комментарий от @siwei-shen, но вам нужен флаг -o
для создания нескольких шаблонов. Флаг -o
означает 'или'
find . -type f -not -name '*ignore1' -o -not -name '*ignore2' | xargs rm
Ответ 15
Вы можете сделать это с помощью команды lines
сначала определите массив с именем файлов, которые вы не хотите исключать
$ files=( backup.tar.gz script.php database.sql info.txt )
После этого пропустите все файлы в каталоге, который вы хотите исключить, проверяя, находится ли имя файла в массиве, который вы не хотите исключать, если он не удаляет файл.
$ for file in $(ls); do if [[ ! " ${files[@]} " ~= "$file" ]];then rm "$file";fi;done
Вот оно!