Видаліть усі, крім одного (або більше) типів файлів


20

Я намагався знайти команду для видалення всіх файлів у папці, але це не такий тип файлу. Але, здається, мені не пощастило. Що я намагався поки що:

set extended_glob
rm !(*.dmg)
# this returns zsh:number expected

rm ./^*.dmg
# this returns no matches found 

Я використовую версію zsh zsh 5.0.2 (x86_64-apple-darwin13.0.1).

Відповіді:


22

Цей extended_globпараметр дає вам власний розширений глобальний синтаксис zsh .

setopt extended_glob
rm -- ^*.dmg
rm -- ^*.(dmg|txt)

Ви можете встановити ksh_globможливість отримати ksh globs . Пам’ятайте, що у загальному випадку, коли негативна закономірність є останньою справою у слові, zsh може проаналізувати круглі дужки як глобальні класифікатори (це не робиться в режимі емуляції ksh).

setopt ksh_glob
rm -- !(*.dmg|*.txt)
setopt no_bare_glob_qual
rm -- !(*.dmg)

Це, здається, не працює. Коли я бігаю, rm -r secrets/!(directory)він постійно просить number expectedабо іноді це дає меніevent not found: directory
CMCDragonkai

@CMCDragonkai "очікуване число" вказує на те, що ви не встановили ksh_globпараметр. "Подія не знайдена: каталог" вказує на те, що ви використовуєте bash (який також розуміє !(…)синтаксис, але лише після shopt -s extglob).
Жиль "ТАК - перестань бути злим"

Як я міг запускати баш, коли я був у своїй команді zsh?
CMCDragonkai

Для мене setopt ksh_glob; echo !(a|b)працює, поки setopt ksh_glob; echo !(a)немає ("очікується кількість") ...
ThiefMaster

@TentistMaster У мене була така ж проблема. Це помилка?
CodeTower

5

Ви можете використовувати findзамість своєї оболонки:

find . -mindepth 1 -maxdepth 1 ! -name "*.dmg" -delete

Від man find:

   ! expr True  if  expr  is false.  This character will also usually need
          protection from interpretation by the shell.
   -name pattern
          Base of file name (the path with the leading directories removed)
          matches shell pattern pattern. 
   -delete
          Delete  files; true if removal succeeded.  If the removal failed,
          an error message is issued.  If -delete fails, find's exit status
          will be nonzero (when  it eventually exits).  Use of -delete 
          automatically turns on the -depth option.

Якщо ви не можете скористатися findз будь-якої причини, ось спосіб зробити це zsh(або іншими оболонками). zshБудучи zsh, мабуть, є простіший спосіб зробити це, але оскільки я bashхлопець, це я придумав:

for file in *; do if [[ ! "$file" == *.dmg ]]; then rm $file; fi; done

на жаль, щоразу, коли я використовую функцію find у своєму mac, він просто закінчує поточний сеанс zsh без будь-якого повідомлення. У вас однакова проблема? find [Process completed]
Дзунг Нгуен

1
@nXqd див. оновлену відповідь, як зробити це без find. Я пропоную вам поставити запитання щодо своєї findпроблеми, але цього не повинно статися. Якщо це зробити, включіть результат type -a find.
terdon

1
Навіть у bash є більш просте рішення:, rm !(*.dmg)after shopt -s extglob.
Жил "ТАК - перестань бути злим"

@terdon дякую за поради щодо налагодження в оболонці. його висновок здається правильним:find is a shell function find is /usr/bin/find
Дзунг Нгуен

@nXqd, що невірно, це не повинна бути функцією оболонки, вона повинна бути лише такою /usr/bin/find. У вас є функція, яка називається findвизначеною в одному з ваших файлів конфігурації bash. Оскільки ви перебуваєте на OSX, це, мабуть ~/.profile.
тердон

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.