开发者

How does this bash function for removing all but some files work?

开发者 https://www.devze.com 2023-02-06 16:19 出处:网络
I\'ve found the following script on commandlinefu.com (the example is not online anymore): rmbut() { local x=(\"$@\")

I've found the following script on commandlinefu.com (the example is not online anymore):

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

It deletes all files and directories but the ones named on the command line.

Could you explain the following:

  • What is happening on the first line? $@ means all arguments, but why is it put inside parentheses?
  • I've read about IFS but never actually used it, what is its usage here?
  • What is 开发者_JAVA百科achieved with *[!"${x[*]}"]? I can't understand how to split it into something I know.


local x=("$@") creates an array which is a copy of all the arguments ($@ is itself an array).

IFS=, sets the internal field separator to a comma.

IFS=, rm -rf *[!"${x[*]}"] says to remove all files that do not end in any character passed as arguments. Since * is used as the index to the array and the variable is quoted it is expanded to a single string and the spaces that would normally separate the elements of the array are replaced by the contents of IFS (a comma in this case).

rmbut a b c

resolves to rm -rf *[!a,b,c] which would also not remove files that end in a comma.

I think the function could be simplified to:

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

but its behavior would be subtly different. This version sets IFS to null so the example above would resolve to rm -rf *[!abc] which would remove files that end in a comma (a comma would have to be passed explicitly as an argument to preserve such files). However, that behavior could be returned by setting IFS=, (it's simply not necessary to copy the array).


# create an array x, containing arguments to the function
local x=("$@")

# unset the IFS variable. This make double quoted arrays expand to single words w/o separators
IFS=

# remove files matching a pattern, i.e. not ending with a character from the array x
rm -rf *[!"${x[*]}"]

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号