删除除一种(或多种)文件类型外的所有文件类型


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)

Answers:


22

extended_glob选项提供zsh自己的扩展glob语法

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

您可以设置ksh_glob获取ksh globs的选项。请注意,在通常情况下,否定模式是单词中的最后一句话,zsh可能会将括号解析为glob限定符(在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 2014年

@CMCDragonkai“预期数量”表示您未设置该ksh_glob选项。“未找到事件:目录”表示您正在运行bash(它也了解!(…)语法,但仅在之后shopt -s extglob)。
吉尔斯(Gillles)“所以-别再邪恶了”

当我在zsh shell中时,如何运行bash?
CMCDragonkai 2014年

对我来说,setopt ksh_glob; echo !(a|b)虽然setopt ksh_glob; echo !(a)没有工作(“预期数量”)...
ThiefMaster

@ThiefMaster我有同样的问题。是虫子吗?
CodeTower

5

您可以使用find而不是shell:

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

不幸的是,每当我在Mac中使用find时,它只会退出当前的zsh会话,而不会发出任何通知。你有同样的问题吗?find [Process completed]
Dzung Nguyen

1
@nXqd请参阅更新的答案,以获取不使用它的方法find。我建议您find尽管发布有关您的问题的问题,但这不应该发生。如果这样做,请包含的输出type -a find
terdon

1
即使在bash中,也有一个更简单的解决方案:rm !(*.dmg)在之后shopt -s extglob
吉尔斯(Gilles)'所以

@terdon感谢您在Shell中的调试提示。它的输出似乎是正确的:find is a shell function find is /usr/bin/find
Dzung Nguyen

@nXqd是不正确的,它不应是shell函数,而应仅是/usr/bin/find。您有一个find在bash配置文件中定义的函数。由于您使用的是OSX,因此可能是~/.profile
terdon

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.