让下面的脚本来说明我的困境..
#!/bin/zsh
STUFF=( moose-hoof ovary clydsedale )
echo ${MINE=$(printf "MY-%s " $STUFF)}
echo ${MINE_EXP=${STUFF/^/MY-}}
MY-驼鹿蹄 MY-卵巢 MY-clydsedale
驼鹿蹄子房 clydsedale
允许在数组的每个元素上进行字符串连接的正确扩展标志是什么?
答案1
使用$^array
。
它将数组转换为数组的大括号扩展。至于在什么时候a=(foo bar baz)
,$^a
会有点像{foo,bar,baz}
。
$ a=(foo bar baz)
$ echo prefix${^a}suffix
prefixfoosuffix prefixbarsuffix prefixbazsuffix
为了复用数组:
$ a=(1 2 3) b=(a b c)
$ echo $^a$^b
1a 1b 1c 2a 2b 2c 3a 3b 3c
当然,如果前缀或后缀包含 shell 特殊字符(例如;
分隔命令或分隔单词的空格,或$"'&*[?~
...),则必须将它们括起来:
echo 'p r e f i x '$^a' s u f f i x'
与csh
's 相同(以及 bash、ksh、zsh):
echo 'p r e f i x '{foo,bar,baz}' s u f f i x'
$^a
本身不得被引用,"foo${^a}bar"
将扩展为一单词。您希望被引用的一种情况是当您想保留空元素时,$^array
与 for 相同。$array
然后,您需要引用数组扩展并使用标志(@)
或"${array[@]}"
语法(让人想起 Bourne shell 的"$@"
):
$ array=(x '')
$ printf '<%s>\n' $array # empties removed
<x>
$ printf '<%s>\n' "$array" # array elts joined with spaces
<x >
$ printf '<%s>\n' "${(@)array}" # empties preserved
<x>
<>
$ printf '<%s>\n' "$array[@]" # empties preserved
<x>
<>
$ printf '<%s>\n' $^array$^array # empty removed
<xx>
<x>
<x>
$ printf '<%s>\n' "$^array$^array" # concatenation of joined arrays
<x x >
$ printf '<%s>\n' "$^array[@]$^array[@]" # multiplexing with empties preserved
<xx>
<x>
<x>
<>
答案2
虽然这是一个相当古老的线程,但我想添加我最近的发现来做同样的事情参数扩展代替:
${name/pattern/repl}
...
该模式可以以“#”开头,在这种情况下,该模式必须在字符串的开头匹配,或者以“%”开头,在这种情况下,它必须在字符串的末尾匹配,或 '#%' 在这种情况下,模式必须匹配整个字符串。 repl 可以是空字符串,在这种情况下,最后的“/”也可以省略。在其他情况下,要引用最后的“/”,其前面应有一个反斜杠;如果“/”出现在替换参数内,则不需要这样做。另请注意,如果“#”、“%”和“#%”出现在替换参数内,即使在开头,它们也不会处于活动状态。
这允许在字符串的开头/结尾匹配模式,并且没有限制只能使用模式,#
或者%
它可以用于前缀和后缀数组:
$ array=(foo bar baz)
$ echo ${array/#/prefix_}
prefix_foo prefix_bar prefix_baz
$ echo ${array/%/_suffix}
foo_suffix bar_suffix baz_suffix
虽然对于字符串来说肯定没有那么方便,因为它们可以更容易地操作,但它仍然是可行的:
$ string="bar"
$ echo ${string/#/foo_}
foo_bar
$ echo ${string/%/_baz}
bar_baz