2011-01-26 47 views
5

我发现下面的脚本上commandlinefu.com(例子中是不在线了):这个bash函数是如何移除除了一些文件之外的所有文件的?

rmbut() { 
    local x=("[email protected]") 
    IFS=, rm -rf *[!"${x[*]}"] 
} 

它删除所有的文件和目录,但指定的命令行上的人。

你能解释下:

  • 什么是第一行发生了什么? [email protected]表示所有参数,但它为什么放在圆括号内?
  • 我已阅读关于IFS但从未实际使用过它,它在这里有什么用处?
  • *[!"${x[*]}"]实现了什么?我无法理解如何将它分解成我知道的东西。
+0

你确定那些是“local x ..”行上的括号(),或者它们是大括号{}或括号[]。它有所作为。另外,从函数的外观来看,它只是删除除函数参数指定的基本名之外的所有文件。 – kvista 2011-01-26 13:48:34

+0

是的,括号是正确的。这是函数的目的,很明显,我想知道为什么^^ – 2011-01-26 14:00:18

回答

4

local x=("[email protected]")创建一个阵列,其是所有参数的副本([email protected]本身就是一个数组)。

IFS=,将内部字段分隔符设置为逗号。

IFS=, rm -rf *[!"${x[*]}"]表示删除所有不以任何字符结尾的文件作为参数传递。由于*被用作数组的索引并且变量被引用,所以它被扩展为单个字符串,并且通常将数组元素分隔的空格被IFS(在这种情况下为逗号)的内容替换。

rmbut a b c 

解决为rm -rf *[!a,b,c]这也不会删除以逗号结尾的文件。

认为功能可以简化为:

rmbut() { 
    IFS= rm -rf *[!"$*"] 
} 

,但它的行为会稍有不同。此版本将IFS设置为空,因此上述示例将解析为rm -rf *[!abc],其中删除以逗号结尾的文件(逗号将不得不作为参数显式传递以保留此类文件)。但是,该行为可以通过设置IFS=,(它根本不需要复制数组)来返回。

3

#创建的数组x,包含函数的自变量
local x=("[email protected]")

#取消设置IFS变量。这使得双引号阵列扩展到单个字的w/o隔板
IFS=

#删除文件相匹配的图案,即,不是与从阵列的字符结束X
rm -rf *[!"${x[*]}"]

+0

@eugene y:你写了`IFS =`,但原来是'IFS =',你有错字还是逗号?将IFS从行的其他内容中分离出来? – 2011-01-26 14:02:28

相关问题