我在commandlinefu.com上找到了下面的脚本(该示例不再在线):
rmbut() {
local x=("$@")
IFS=, rm -rf *[!"${x[*]}"]
}
它删除所有文件和目录,但保留命令行中命名的那些。
请解释以下内容:
- 第一行发生了什么?$@表示所有参数,但为什么要放在括号里? - 我曾经了解过IFS,但从未真正使用它,在这里它的用法是什么? - 通过*[!"${x[*]}"]实现了什么?我不明白如何将其分割成我知道的东西。
我在commandlinefu.com上找到了下面的脚本(该示例不再在线):
rmbut() {
local x=("$@")
IFS=, rm -rf *[!"${x[*]}"]
}
local x=("$@")
创建一个数组,该数组是所有参数的副本($@
本身就是一个数组)。
IFS=,
将内部字段分隔符设置为逗号。
IFS=, rm -rf *[!"${x[*]}"]
表示删除不以任何传递的字符结尾的所有文件。由于*
用作数组的索引并且变量被引用,因此它被扩展为单个字符串,并且通常用于分隔数组元素的空格被替换为IFS
的内容(在这种情况下是逗号)。
rmbut a b c
解析为rm -rf *[!a,b,c]
,但这也不会删除以逗号结尾的文件。
我认为这个函数可以简化为:
rmbut() {
IFS= rm -rf *[!"$*"]
}
IFS
设置为空,因此上面的示例将解析为rm -rf *[!abc]
,这将删除以逗号结尾的文件(必须显式传递逗号作为参数以保留这些文件)。但是,通过设置IFS=,
可以返回该行为(无需复制数组即可完成)。# 创建一个包含函数参数的数组x
local x=("$@")
# 取消IFS变量设置,这使得双引号数组扩展为没有分隔符的单个单词
IFS=
# 删除匹配模式的文件,即不以数组x中的任何字符结尾
rm -rf *[!"${x[*]}"]
IFS=
,但原本应该是IFS=,
,你是打错了还是逗号是用来分隔该行中的其他内容和IFS
的? - Alberto Zaccagnitouch abc bcd cde; rmbut bcd # 仅删除"cde"
- Eugene YarmashIFS
之后是否加上,
都不行,感谢你指出这一点。 - Alberto Zaccagni