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:
$@
means all arguments, but why is it put inside parentheses?IFS
but never actually used it, what is its usage here?*[!"${x[*]}"]
? I can't understand how to split it into something I know.Using Extended Globbing and Pattern Matching Operators Also, with the ! operator, we can exclude all files we don't want glob to match during deletion. Let's look at the list of pattern matching operators: ?(pattern-list) matches at least zero and at most one occurrence.
Microsoft Windows Browse to the folder containing the files. Click the Type column heading to sort all files by the type of files. Highlight all the files you want to keep by clicking the first file type, hold down Shift , and click the last file.
To remove a directory and all its contents, including any subdirectories and files, use the rm command with the recursive option, -r .
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 functionlocal x=("$@")
# unset the IFS variable. This make double quoted arrays expand to single words w/o separatorsIFS=
# remove files matching a pattern, i.e. not ending with a character from the array xrm -rf *[!"${x[*]}"]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With