121

Мне нужно удалить все файлы в каталоге, но исключить некоторые из них. Например, в каталоге с файлами a b c ... z мне нужно удалить все, кроме u и p . Есть простой способ сделать это?

17 ответов17

143

rm все , но u,p в Баш просто введите:

rm !(u|p)

Для этого необходимо установить следующую опцию:

shopt -s extglob

Смотрите больше: glob - Greg's Wiki

109

Что я делаю в этих случаях, чтобы набрать

rm *

Затем я нажимаю Ctrl+X, *, чтобы развернуть * во все видимые имена файлов.

Затем я могу просто удалить два файла, которые я хочу сохранить из списка, и, наконец, выполнить командную строку.

71

Вы можете использовать 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
    
42

Просто:

mv файлы, которые вы хотите в верхнем каталоге, rm каталог, а затем mv их обратно.

15

В некоторой степени похож на этот ответ, но никаких специальных опций не требуется, насколько мне известно, что "древняя" функциональность поддерживается любой (неопределенно) /bin /sh, похожей на оболочку (например, bash, zsh, ksh и т.д.)

rm [^up]
11

Делаем это без поиска:

ls | grep -v '(u|p)' | xargs rm

(Правка: "u" и "v", как и в других местах здесь, используются как общие версии целых регулярных выражений. Очевидно, вы хотите быть осторожными, чтобы привязать свои регулярные выражения, чтобы избежать совпадения слишком многих вещей.)

Вы определенно будете хотеть сценарий, если вы собираетесь делать большую часть этого, как предлагали другие.

6

В зш:

setopt extended_glob  # probably in your .zshrc

затем

rm ^(u|p)

или же

rm *~(u|p)

Второй будет работать, даже если у вас есть ^ в $histchars для подстановки истории, и, конечно, вы можете поставить произвольный глобус перед ~ .

5

GLOBIGNORE берет разделенный двоеточиями список

GLOBIGNORE=u:p
rm *
3

Еще в эпоху дискет у меня был исполняемый файл dos под названием "Кроме", который временно перемещал вещи из текущего каталога и выполнял команду, так что вы могли бы сказать:

except *.txt del *.*

удалить все, кроме ваших текстовых файлов.

Это было бы довольно тривиально реализовать в виде сценария оболочки, и если это то, что вы, вероятно, будете делать более двух раз, кажется, что это хорошая идея.

3
 find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

Это удалит все файлы, кроме U и P в Unix

2

Для тех, кто предпочитает указывать произвольные сложные шаблоны исключений (охватывающие все затронутые имена файлов) в полном стиле remaxp emacs, posix-awk или posix-extended (см. Страницу поиска man), я бы порекомендовал этот. Это исключает u и p в текущем dir в этом примере. Это может быть удобно для сценариев.

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf
1

Еще один:

for FILE in ./*; do if [[ $FILE != ./u* ]] || [[ $FILE != ./p* ]];then rm $FILE; fi; done;

Это довольно долго, и я не знаю, сможете ли вы легко превратить это в функцию, которая может легко вместить произвольное количество аргументов, но это хорошо работает.

И это чистое совершенство.

1

Использование:

find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete

чтобы удалить все файлы, включая каталоги, кроме файлов u, p и .ext.

1

Вот еще один вариант. Вы можете ввести:

rm -i *

или же:

rm --interactive *

Поэтому rm попросит вас подтвердить удаление каждого файла.

1

Еще одна версия с использованием xargs:

ls -1 | grep -v do_not_delete | xargs -I files rm "files"

Обратите внимание, что xargs -I необходим для правильной обработки имен файлов, включая пробелы.

1

Я всегда использую:

rm [a-o,q-t,v-z]*

Это позволит вам определить, насколько гранулярным вы хотите это сделать. Поэтому, если вы хотите удалить файлы от 0 до 3, вы можете использовать:

rm [a-o,z]*
0

Простой способ, который трудно испортить: допустим, вы хотите удалить все, кроме * .pdf:

mkdir tmp
mv *.pdf tmp
rm *
mv tmp/* .
rm -r tmp

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .