У меня есть много файлов и папок в определенной папке, и я хочу удалить их все; однако я хотел сохранить файлы X, Y и Z.
Есть ли способ, которым я могу сделать что-то вроде: rm * | but NOT grep | X or Y or Z
У меня есть много файлов и папок в определенной папке, и я хочу удалить их все; однако я хотел сохранить файлы X, Y и Z.
Есть ли способ, которым я могу сделать что-то вроде: rm * | but NOT grep | X or Y or Z
Ответы:
Вместо использования rm может быть проще использовать find . Такая команда удалит все, кроме файла с именем «file»
find . \! -name 'file' -delete
Многие версии должны поддерживать глобализацию и сопоставление регулярных выражений.
Вы также можете передать вывод команды find в rm
find . \! -name '*pattern*' -print0 | xargs --null rm
-delete
а также какие файлы будут сохранены при удалении -delete
и \!
.
find
рекурсивен! так что все подкаталоги файлов, не соответствующие ' pattern ', также будут удалены
Использование zsh, с setopt EXTENDED_GLOB
использованием ~
оператора ( кроме )
rm -- *~(x|y|z)
или ^
оператор (отрицание):
rm -- ^(x|y|z)
Но вы, вероятно, должны вместо этого переместить файлы в другое место, а затем удалить все. Это намного безопаснее с точки зрения проскальзывания пальцев, например, попадания слишком рано.
Более поздние версии bash имеют extglob
опцию оболочки, которая дает вам синтаксис для выполнения того, что вы хотите (проверьте вашу справочную страницу в разделе «Расширение пути», чтобы увидеть, есть ли в вашей установленной версии):
$ shopt -s extglob # turn on extended globbing
$ rm !(X|Y|Z)
Чтобы проверить, я предлагаю вам сначала заменить rm
на, echo
чтобы увидеть, является ли список файлов, которые будут удалены, то, что вы ожидаете.
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r
Внимание: запустите команду и, если файлы, которые нужно удалить, являются правильными, запустите ее снова и удалите хеш-символ "#".
Если имена файлов более сложны,
ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r
Опять же, сначала посмотрите на результаты, затем удалите знак хеша.
Эта версия, как предлагается в комментариях, сохраняет некоторые символы и выглядит немного яснее.
ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r
egrep
аргумент на"^(file1|filename2|f1le)$"
a
, b
и a b
первая программа будет удалить - если вы поставите аЬ в Grep часть: "^[ab]$"
a
и , b
но не a b
просто в отличие от ваших намерений. Вторая команда сделает то же самое. И третий тоже. Вы не должны использовать 'ls' в скриптах, за очень, очень редкими исключениями. Просто не делай этого.
Переместите файлы, которые вы хотите сохранить. Поднимитесь на один уровень выше, удалите папку. Пересоздайте папку и переместите эти файлы обратно.
/
, а? Не очень практично. в) Попытка удалить все файлы в вашем $HOME
тоже не очень практична.
Это то, что я настроил как сценарий .sh для выхода из OSX / MacOS, работает достаточно хорошо.
#! /bin/bash
for dir in /PathToFolder/*
do
if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then
echo ${dir}
sudo rm -R $dir user
dscl . -delete $dir
fi
done
exit 0
С GNU-find вы можете использовать ключ -delete, который удаляет каталоги, если они тоже пусты:
find tmp -not -name X -not -name Y -not -name Z -delete
find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -delete
это один из способов обойти это.
tmp
если в нем не было файлов X
/ Y
/ Z
. Примечание !
в качестве стандартного эквивалента GNU -not
( -delete
также является расширением GNU)