Удалите все * .mp4 и * .zip, но некоторые файлы

В одной из моих программ я вызываю команду bash для удаления всех файлов в каталоге, но некоторые:

 bash -c shopt -s extglob shopt -s nullglob rm /path/to/directory/!("file1" | "file2") 

Который для того, что я понимаю, означает «Использовать bash для этой команды, использовать расширенный шаблон, удалить все файлы, кроме тех,

Он работает хорошо, но удаляет каждый файл, кроме тех, которые указаны в команде.

Я хотел бы удалить все .mp4 и .zip в каталог, но те, которые я ввел в команду.

Я думаю, что мне придется добавить * .mp4 и * .zip где-нибудь в команде, но я понятия не имею, где.

EDIT: для ясности мне нужно «Удалить все файлы .mp4 и .zip, но сохраните их»

3 Solutions collect form web for “Удалите все * .mp4 и * .zip, но некоторые файлы”

Шаблон !("file1" | "file2") соответствует любому файлу, кроме file1␣ или ␣file2 где – пробел. То, как вы цитировали это, вводит в заблуждение: это эквивалентно !(file1 | file2) или !("file1 "|" file2 )`.

В bash нет способа комбинировать отрицательный шаблон с положительным шаблоном, чтобы сказать «все из них, кроме тех». В zsh вы можете написать

 setopt extended_glob rm /path/to/directory/*.(mp4|zip)~(keep*|1234.zip) 

для удаления this.mp4 и that.zip но не keep-this.mp4 или 1234.zip .

В bash вы можете установить переменную GLOBIGNORE чтобы исключить определенные шаблоны из всех совпадений.

 shopt -s extglob GLOBIGNORE='keep*:1234.zip' rm /path/to/directory/*.(mp4|zip) unset GLOBIGNORE 

Кроме того, вы можете использовать find , который позволяет создавать произвольно сложные булевы выражения.

 find /path/to/directory \( -name '*.mp4' -o -name '*.zip' \) ! -name 'keep*' ! -name '1234.zip' -delete 

Обратите внимание, что find recurses в подкаталоги. Если это нежелательно, добавьте -maxdepth 1 после /path/to/directory .

Если ваша find не понимает -maxdepth (это обычная, но не стандартная), вместо этого используйте -type d -prune -o . Если ваша find не понимает -delete (такое же замечание), вместо этого используйте -exec rm {} + .

Существует несколько способов:

  • Использовать find (портативный, поскольку он не нуждается в конкретной оболочке [bash])
  найти .  -maxdepth 1!  -name "exclude" -delete 

или если у вас несколько шаблонов:

  найти .  -maxdepth 1!  \ (-name "exclude" -o -name "exclude2" \) -exec rm -f {} \ + 
  • Используйте переменную GLOBIGNORE (только для bash)
  export GLOBIGNORE = исключить: exclude1: mask * 

Это исключает упомянутые файлы и маски из глобуса. После этого вы можете указать rm your_pattern

Вы можете попробовать это раньше с помощью ls

Я бы нашел. Однако ваша проблема – это пробелы.

rm /path/to/directory/!("file1" | "file2")

такая же, как rm "/path/to/directory/!(file1" "|" "file2)"

не rm "/path/to/directory/!(file1|file2)"

ознакомьтесь с правилами цитирования оболочки.

  • Как удалить файл без использования rm?
  • Почему удаление каталогов генерирует сообщения об ошибках с помощью find -exec?
  • Помощь с сортировкой после запуска rm -rf / * в качестве пользователя без root
  • Не удается удалить определенные каталоги в определенном родительском каталоге
  • Почему OS X не позволяет мне переименовать файл?
  • Найти и удалить подкаталоги без ошибок?
  • Не удалось создать файл rm: превышена дисковая квота
  • Поведение rm - как предотвратить удаление содержимого установленных точек
  • Что происходит шаг за шагом при использовании «rm -rf directory»?
  • Есть ли способ предотвратить удаление определенных файлов из пользовательской директории?
  • Могу ли я использовать `rm` только при использовании globbing? (либо в bash, либо в zsh, либо в обоих)
  • Interesting Posts
    Linux и Unix - лучшая ОС в мире.