======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