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