删除除具有特定扩展名的文件以外的所

时间:2014-06-05 01:32:52

标签: shell cygwin rm

这将删除以.a.b

结尾的所有文件
$ ls *.a
a.a  b.a  c.a

$ ls *.b
a.b  b.b  c.b

$ rm *.a *.b

除了以*.**.a结尾的文件外,我将如何反复删除以*.b结尾的所有文件?

4 个答案:

答案 0 :(得分:1)

您可以在bash中启用扩展的glob:

shopt -s extglob

然后你可以使用:

rm *.!(a|b)

删除所有以*.*结尾的文件,但以*.a*.b

结尾的文件除外

更新:(感谢@ mklement0)这是一种通过在extglob中执行此操作来本地化设置subshell(不改变全局状态)并使用中间变量:

(shopt -s extglob; glob='*.!(a|b)'; rm $glob)

答案 1 :(得分:1)

链接的答案提供了有用的信息,虽然这个问题有点含糊不清,答案使用了不同的解释。

您案例中最简单的方法可能是({3}}的简化版本):

 (GLOBIGNORE='*.a:*.b'; rm *.*)
  • 请注意使用子shell((...))来本地化设置GLOBIGNORE变量。
  • 分配给GLOBIGNORE的模式必须为: - 已分隔。

此方法的吸引力在于您可以使用单个子shell而不更改全局状态

相比之下,使用shopt -s extglob获得单个子shell需要一些技巧

(shopt -s extglob; glob='*.!(a|b)'; echo $glob)

请注意强制使用中间变量,如果没有该中间变量,命令将中断(因为在执行命令之前将扩展文字glob,此时尚未识别扩展的globbing语法)


警告:使用GLOBIGNORE会产生意想不到的副作用(错误?):

如果GLOBIGNORE 设置 - 任何值 - **.*的路径名扩展就像shell选项dotglob生效一样 - 即使它不是 换句话说:如果设置了GLOBIGNOREGLOBIGNORE中的模式未明确豁免的隐藏文件总是匹配{{ 1}}和*

*.*默认为OFF,导致dotglob不包含隐藏的文件(如果未设置*,默认情况下为true)。< / p>

如果您还想在使用GLOBIGNORE排除隐藏文件,请添加以下模式:GLOBIGNORE;适用于这个问题,你得到:

.*

相比之下,在启用 (GLOBIGNORE='*.a:*.b:.*'; rm *.*) shell选项后使用扩展通配符会尊重extglob选项。

答案 2 :(得分:0)

有一些shell能够做到这一点(我认为?),但是bash默认不是。如果您在Cygwin上运行bash,则可以执行以下操作:

rm $(ls -1 | grep -v '.*\.a' | grep -v '.*\.b')
  • ls -1(这是一个)列出当前目录中每行一个文件。
  • grep -v '.*\.a'返回以.a
  • 结尾的所有匹配项
  • grep -v '.*\.b'返回以.b
  • 结尾的所有匹配项

答案 3 :(得分:0)

有时候最好不要坚持以某种方式解决问题。对于“以某种棘手的方式对某些文件采取行动”的一般问题,find可能是您能找到的最好的全能工具。

find . -type f -maxdepth 1 ! -name \*.[ab] -delete

如果要递归到子目录,请忽略-maxdepth 1