While putting together a script, I came across this command:
f=${file##*/}
I am curious to know, what does ## in this line mean?
While putting together a script, I came across this command:
f=${file##*/}
I am curious to know, what does ## in this line mean?
In bash, it removes a prefix pattern. Here, it's basically giving you everything after the last path separator /, by greedily removing the prefix */, any number of characters followed by /):
pax> fspec=/path/to/some/file.txt ; echo ${fspec##*/}
file.txt
Greedy in this context means matches as much as possible. There's also a non-greedy variant (matches the smallest possible sequence), and equivalents for suffixes:
pax> echo ${fspec#*/} # non-greedy prefix removal
path/to/some/file.txt
pax> echo ${fspec%%/*} # greedy suffix removal (no output)
pax> echo ${fspec%/*} # non-greedy suffix removal
/path/to/some
The ##*/ and %/* are roughly equivalent to what you get from basename and dirname respectively, but within bash so you don't have to invoke an external program:
pax> basename ${fspec} ; dirname ${fspec}
file.txt
/path/to/some
For what it's worth, the way I remember the different effects of ##, %%, #, and %, is as follows. They are "removers" of various types.
Because # often comes before a number (as in #1), it removes stuff at the start. Similarly, % often comes after a number (50%) so it removes stuff at the end.
Then the only distinction is the greedy/non-greedy aspect. Having more of the character (## or %%) obviously means you're greedy, otherwise you'd share them :-)