Как удалить все файлы в каталоге, кроме некоторых?
Мне нужно удалить все файлы в каталоге, но исключить некоторые из них. Например, в каталоге с файлами a b c ... z
Мне нужно удалить все, кроме u
а также p
, Есть простой способ сделать это?
17 ответов
Что я делаю в этих случаях, чтобы набрать
rm *
Затем я нажимаю Ctrl+X,*, чтобы развернуть *
во все видимые имена файлов.
Затем я могу просто удалить два файла, которые я хочу сохранить из списка, и, наконец, выполнить командную строку.
К rm
Все кроме u,p
в Bash просто введите:
rm !(u|p)
Для этого необходимо установить следующую опцию:
shopt -s extglob
Смотрите больше: glob - Greg's Wiki
Ты можешь использовать find
find . ! -name u ! -name p -maxdepth 1 -type f -delete
!
отменяет следующее выражение-name
указывает имя файла-maxdepth 1
сделает процесс поиска только в указанной директории (find
по умолчанию проходит каталоги)-type f
будет обрабатывать только файлы (а не, например, каталоги)-delete
удалит файлы
Затем вы можете настроить условия, просмотрев справочную страницу поиска.
Обновить
- Имейте в виду, что порядок элементов выражений является значительным (см. Документацию)
Сначала проверьте свою команду, используя
-print
вместо-delete
find . ! -name u ! -name p -maxdepth 1 -type f -print
Просто:
mv
файлы, которые вы хотите в верхнем каталоге, rm
каталог, а затем mv
их обратно.
В некоторой степени похож на этот ответ, но никаких специальных опций не требуется, насколько я знаю, что "древняя" функциональность поддерживается любой (смутно) / bin / sh, похожей на оболочку (например, bash, zsh, ksh и т. Д.)
rm [^up]
Делаем это без поиска:
ls | grep -v '(u|p)' | xargs rm
(Отредактируйте: "u" и "v", как и в других местах здесь, используются в качестве универсальных версий целых регулярных выражений. Очевидно, что вам нужно быть осторожным, чтобы привязать свои регулярные выражения, чтобы избежать совпадения слишком многих вещей.)
Вы определенно будете хотеть сценарий, если вы собираетесь делать большую часть этого, как предлагали другие.
В зш:
setopt extended_glob # probably in your .zshrc
затем
rm ^(u|p)
или же
rm *~(u|p)
Второй будет работать, даже если у вас есть ^
в $histchars
для замены истории, и, конечно, вы можете поставить произвольный шар перед ~
,
GLOBIGNORE берет разделенный двоеточиями список
GLOBIGNORE=u:p
rm *
find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;
Это удалит все файлы, кроме U и P в Unix
Еще в эпоху дискет у меня был исполняемый файл dos под названием "Кроме", который временно перемещал вещи из текущего каталога и выполнял команду, так что вы могли бы сказать:
кроме *.txt del *.*
удалить все, кроме ваших текстовых файлов.
Это было бы довольно тривиально реализовать в виде сценария оболочки, и если вы будете делать это более двух раз, кажется, что это хорошая идея.
Here's another variant. Вы можете ввести:
rm -i *
или же:
rm --interactive *
Так rm
will ask you to confirm deleting of each file.
Использование:
find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
чтобы удалить все файлы, включая каталоги, кроме файлов u, p и.ext.
Еще один:
for FILE in ./*; do if [[ $FILE != ./u* ]] || [[ $FILE != ./p* ]];then rm $FILE; fi; done;
Это довольно долго, и я не знаю, сможете ли вы легко превратить это в функцию, которая может легко разместить произвольное количество аргументов, но это работает хорошо.
И это чистая доброта.
Для тех, кто предпочитает указывать произвольные сложные шаблоны исключений (охватывающие все затронутые имена файлов) в полном стиле remaxp emacs, posix-awk или posix-extended (см. Страницу поиска man), я бы порекомендовал этот. Исключает u
а также p
в текущем каталоге в этом примере. Это может быть удобно для сценариев.
find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf
Я всегда использую:
rm [a-o,q-t,v-z]*
Это позволит вам определить, насколько гранулярным вы хотите это сделать. Поэтому, если вы хотите удалить файлы от 0 до 3, вы можете использовать:
rm [a-o,z]*
Простой способ, который сложно испортить: допустим, вы хотите удалить все, кроме *.pdf:
mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp
Еще одна версия с использованием xargs
:
ls -1 | grep -v do_not_delete | xargs -I files rm "files"
Обратите внимание, что xargs -I
необходим для правильной обработки имен файлов, включая пробелы.