======Parameter Expansion Flags======
Expansion Flags are very powerful. However they are sometimes not that easy to understand
by just reading the manual. So, let's look at some examples for their usage.
If you prefer German over English, this page was originally based on a blog posting:
* [[http://www.bewatermyfriend.org/posts/2006/06-28.22-28-50-tooltime.html|ftblog: Tooltime: zsh #8]]
=====(#) Flag=====
Note, that the (#) flag and the # modifier are two different things.
See [[scripting:parammod|Parameter Modifiers]] for details.
zsh% i="4*12+10"
zsh% print \"${i}\" \"${(#)i}\"
"4*12+10" ":"
zsh% ascii ":"
ASCII 3/10 is decimal 058, hex 3a, octal 072, bits 00111010: prints as `:'
Official name: Colon
So, calculating 4*12+10 equals 58. The ''ascii'' command tells us, that 58 is the decimal
value for the : sign in ascii-encoding. That means ${(#)param} calculates the string in
$param as a formula and expands the result as the corresponding character from the ascii
table.
=====(%) Flag=====
This is a simple one. You get the same %-expansions as you would expect from your
prompt variables:
zsh% cd /usr/src
zsh% var="%/ - %D - %% - Howdy..."
zsh% print ${(%)var}
/usr/src - 07-06-06 - % - Howdy...
=====(@) Flag=====
This flag enables you to get separate words from arrays, although double-quotes are in effect:
zsh% foo=( bar baz foo\ bar bar\ baz )
zsh% print -l "${foo}"
bar baz foo bar bar baz
zsh% print -l "${(@)foo}"
bar
baz
foo bar
bar baz
=====(A)/(AA) Flags=====
[[scripting:parammod|Parameter Modifiers]] give enable you to do direct variable
assignment: ''${...::=...}'' and the like. Now, this flag let's you do the same for
arrays and associative arrays:
zsh% print -l ${(A)foo::=foo bar baz}
foo bar baz
zsh% print ${#foo}
1
Ouch, here you see the SH_WORDSPLIT issue, that was discussed on the [[scripting:paramexp|Parameter Expansion Page]].
Let's use = to enable shwordsplit temporarily.
zsh% print -l ${(A)=foo::=foo bar baz}
foo
bar
baz
zsh% print ${#foo}
3
Alright, and now let's do this for associative arrays:
zsh% print -l ${(AA)=foo::=foo0 bar foo1 baz}
bar
baz
zsh% print $foo[foo0] - $foo[foo1]
bar - baz
zsh% print ${#foo}
2
=====(c) Flag=====
This is a simple one again: If used with the ''${#...}'' modifier, it returns the
length of the string you would get, if the array elements would have been joined
by spaces:
zsh% foo=( bar baz foobar )
zsh% print ${(c)#foo}
14
=====(C) Flag=====
Again, simple: This flag capitalizes the first letter of every word in
an array:
zsh% foo=( bar baz foobar )
zsh% print ${(C)foo}
Bar Baz Foobar
=====(e) Flag=====
This one is a beast ;-) - it enforces all forms of substitutions and expansions
on the value of a parameter:
zsh% foo='$(print $ZSH_VERSION)'
zsh% print ${(e)foo}
4.3.2
zsh% foo='print ${(c)#foo}'
zsh% print ${(e)foo}
print 16
=====(f)/(F) Flags=====
These flags are short forms of ''ps:\n:'' and ''pj:\n:''.
(f) is specially useful to read lines of files into arrays:
zsh% cat > file
Typing one line.
And another one.
zsh% foo=($(
(F) joins array elements with ''\n''.
zsh% foo=( foo bar baz )
zsh% print ${(F)foo}
foo
bar
baz
=====(k)/(v) Flags=====
If you got an associative array, (k) returns the keys rather than the values:
zsh% declare -A foo
zsh% foo=( foo bar foz baz )
zsh% print ${foo}
bar baz
zsh% print ${(k)foo}
foo foz
zsh% print ${${(k)foo}[1]}
foo
zsh% print ${${(k)foo}[2]}
foz
Togehter with (v) you get both:
zsh% declare -A foo
zsh% foo=( foo bar foz baz )
zsh% print ${(kv)foo}
foo bar foz baz
=====(U)/(L) Flags=====
It's getting simpler again. These flags do upper/lowercase conversion:
zsh% foo=( wEirD wORDs )
zsh% print ${(U)foo}
WEIRD WORDS
zsh% print ${(L)foo}
weird words
=====(M) Flag=====
This flag is particularly useful when doing pattern matching on array elements,
as it reverses the behaviour of the ''${...:#...}'' modifier.
zsh% setopt extended_glob
zsh% print -l ${path}
/home/ft/bin
/bin
/usr/bin
/usr/local/bin
/opt/opera/bin
/usr/games
zsh% print -l ${path:#(*/)#bin[/]#}
/usr/games
zsh% print -l ${(M)path:#(*/)#bin[/]#}
/home/ft/bin
/bin
/usr/bin
/usr/local/bin
/opt/opera/bin
zsh% print -l ${(M)path:#^(*/)#bin[/]#}
/usr/games
=====(o)/(O) Flags=====
This let's you reorder arrays.
Subflags:
* (a): The array sorting, thus (Oa) gives reverse array order.
* (i): case insensitive
* (n): numeric order
zsh% foo=( 03foo 01bAR 02BAZ 04baz 06bar 05Foo )
zsh% print ${(Oa)foo}
05Foo 06bar 04baz 02BAZ 01bAR 03foo
zsh% print ${(on)foo}
01bAR 02BAZ 03foo 04baz 05Foo 06bar
zsh% print ${(On)foo}
06bar 05Foo 04baz 03foo 02BAZ 01bAR
=====(P) Flag=====
This flag interprets the content of a variable as a variable name:
zsh% foo=( wEirD wORDs )
zsh% bar="foo"
zsh% print ${(L)${(P)bar}}
weird words
=====(q)/(Q) Flags=====
This adds quoting levels:
zsh% foo='This is a damn parameter!'
zsh% echo ${(q)foo}
This\ is\ a\ damn\ parameter\!
zsh% print ${(qq)foo}
'This is a damn parameter!'
zsh% print ${(qqq)foo}
"This is a damn parameter!"
zsh% print ${(qqqq)foo}
$'This is a damn parameter!'
This is needed sometimes, when you ''eval'' a parameter.
The (Q) flag works in the opposite direction, it removes quoting levels.
=====(t) Flag=====
The (t) flag displays the type of a parameter.
zsh% foo='This is a damn parameter!'
zsh% print ${(t)foo}
scalar
zsh% foo=( foo bar baz )
zsh% print ${(t)foo}
array
=====(u) Flag=====
If elements of an array got the same value multiple times, this returns that
value only once:
zsh% foo=(foo foo bar foo baz bar foo bar)
zsh% print ${(u)foo}
foo bar baz
=====(V) Flag=====
This is like a builtin ''cat -v'':
zsh% foo=$'\e[35mHello World.'
zsh% print ${foo}
Hello World.
(( The control sequence makes this 'Hello World.' appear in magenta. ))
zsh% print ${(V)foo}
^[[35mHello World.
=====(w)/(W) Flags=====
With (w) you can count words (and in connection with (s) it even let's you define
how counting is done). (W) is similar, it also counts "empty" words.
zsh% foo=$'Hello World, mere mortal.'
zsh% print ${(w)#foo}
4
zsh% print ${(ws:,:)#foo}
2
zsh% foo=$'Hello World,, mere mortal.'
zsh% print ${(Ws:,:)#foo}
3
=====(X) Flag=====
This turns on error messages for the (Q) and (e) flags as well as pattern matching
in the form of ''${...#...}''. I didn't understand this flag correctly myself, but
Bart Schaefer enlightened me in [[http://www.zsh.org/mla/users/2006/msg00645.html|zsh-users #10451]]:
zsh% foo="two ' matched ' quotes"
zsh% print ${(Q)foo}
two matched quotes
zsh% foo="only one ' quote"
zsh% print ${(Q)foo}
only one ' quote
zsh% print ${(XQ)foo}
zsh: unmatched '
=====(z) Flag=====
...splits scalars using the shall parser:
zsh% foo="bar\ baz beer booze"
zsh% print ${${(z)foo}[2]}
beer
=====(j:...:) Flag=====
This joins array elements.
zsh% foo=(foo bar baz)
zsh% print ${(j:.:)foo}
foo.bar.baz
zsh% print ${(j:_-_:)foo}
foo_-_bar_-_baz
=====(s:...:) Flag=====
The opposite of ''(j:...:)'', it splits a scalar into a list.
zsh% foo="foo_-_bar_-_baz"
zsh% print -l ${(s:_-_:)foo}
foo
bar
baz
=====(l:expr::string1::string2:) Flag=====
Pad a string on the left side:
zsh% foo="foo"
zsh% bar="foo bar baz"
zsh% for i in foo bar ; do var="$i" ; print ${(l:20::.::/:)${(P)var}} ; done
................/foo
......../foo bar baz
=====(r:expr::string1::string2:) Flag=====
Pad a string on the right side:
zsh% foo="foo"
zsh% bar="foo bar baz"
zsh% for i in foo bar ; do var="$i" ; print ${(r:20::.:: :)${(P)var}} ; done
foo ................
foo bar baz ........
=====(p) Flag=====
(p) works with (j), (s), (l) and (r). It recognizes the escape sequences know
by the print builtin.
zsh% foo="bar
beer
booze"
zsh% print ${(s:\n:)foo} ;: this will not work
bar
beer
booze
zsh% print ${(ps:\n:)foo} ;: this will
bar beer booze
=====(S) Flag=====
* only makes sense in these expressions: ''${...#...}'', ''${...%...}'', ''${.../...}'' and the like.
Searches/removes are not nailed down to the start/end:
zsh% string="Hampelmann Pampelmannnnnnn-"
zsh% print ${(S)string#am*lmann}
H Pampelmannnnnnn-
zsh% print ${(S)string##am*lmann}
Hnnnnn-
zsh% print ${(S)string%e*n}
Hampelmann Pampnnnnnn-
zsh% print ${(S)string%%e*n}
Hampelmann Pamp-
=====(I) Flag=====
* only makes sense in these expressions: ''${...#...}'', ''${...%...}'', ''${.../...}'' and the like.
Enhances the (S) Flag; searches for the n-th match. Example from the manual page:
zsh% string="which switch is the right switch for Ipswich?"
zsh% for i in {1..4} ; do print ${(SI:${i}:)string#w*ch} ; done
switch is the right switch for Ipswich?
which s is the right switch for Ipswich?
which switch is the right s for Ipswich?
which switch is the right switch for Ips?
=====(B)/(E)/(M)/(N)/(R) Flags=====
These flags affect the (S) flag.
* (B) shows the position, where the matched part starts.
* (E) same as (B), but shows the position of the end.
* (M) displays the matched part.
* (N) displays the length of the matched part.
* (R) displays the non-matching part.
zsh% string="Hampelmann"
zsh% print -l ${(SBEMNR)string#am*lmann} ${(SB)string#am*lmann} \
${(SE)string#am*lmann} ${(SM)string#am*lmann} ${(SN)string#am*lmann} \
${(SR)string#am*lmann}
ampelmann H 2 11 9
2
11
ampelmann
9
H