A solution is proposed that includes:
shopt -s extglob; dir="${dir//+(\/)//}"
Can someone explain (parse) that for me? I understand what it's doing, but not how the syntax works.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityA solution is proposed that includes:
shopt -s extglob; dir="${dir//+(\/)//}"
Can someone explain (parse) that for me? I understand what it's doing, but not how the syntax works.
dir="${dir//+(\/)//}"
is using the ${PARAMETER/PATTERN/STRING}
expansion. Breaking it down in this case (using a syntax reminiscent of Perl's /x
regex modifier, not valid Bash syntax):
${ # start expansion
dir # the parameter being expanded
/ # separates parameter from pattern
/ # double slash means replace all instead of replace first
+(\/) # the pattern we're looking for
/ # separates pattern from replacement
/ # the replacement text
} # end expansion
With extglob
enabled, +(PATTERN)
means one or more occurrences of PATTERN. The pattern \/
matches a slash (the backslash is to indicate that this isn't the slash that separates the pattern and the replacement text), so +(\/)
matches one or more /
characters.
From the bash(1)
man page:
+(pattern-list)
Matches one or more occurrences of the given patterns
So, it is like the +
regex operator, applied to the pattern within the parens.
//
is as per the normal multiple replace expansion syntax... The second double slash //
is made up of two syntactically quite different elements... The first one is the single slash which delimits the search patern from the replacement... the second (final) slash it the actual value of the replacement... The regex is explained in the link and man page... A point of note, is that you can actually mix normal globs with the regex syntax...
Depends on the shell. I use zsh, which has quite a lot of features with it:
Here, I can select case insensitive names:
#!/bin/zsh
setopt extendedglob
for f in (#i)*.(jpeg|jpg|png); do
{
mogrify -scale 1280x1280 $f
exiv2 rm $f
mv $f $f:l
} &
done