假设我们有数组FOO=("hello world" "xyzzy")
。我们要运行thing
工具,将$FOO
的每个元素作为单独的-Z
标志传递,从而产生命令:
thing -Z "hello world" -Z "xyzzy"
这些无效:
# Equivalent to `thing "-Z hello world" "-Z xyzzy"`
thing "${FOO[@]/#/-Z }"
# Equivalent to `thing "-Z hello world -Z xyzzy"`
thing "${FOO[*]/#/-Z }"
# Equivalent to `thing -Z hello world -Z xyzzy`
thing ${FOO[@]/#/-Z }
# Equivalent to `thing -Z hello world -Z xyzzy`
thing ${FOO[*]/#/-Z }
我能做的是在数组的每个元素之间插入一个-Z
:
FOO2=()
for x in "${FOO[@]}"; do FOO2+=("-Z" "$x"); done
thing "${FOO2[@]}"
有没有一种方法不需要显式循环和数组副本?
答案 0 :(得分:2)
bash
≥4.4的新阵列您可以使用空字节定界符(\0
)打印数组,在每个条目前面插入-Z\0
,然后再次将结果读取为数组:
由于bash
,以下解决方案要求mapfile -d
≥4.4。另外,请参阅此答案末尾的hack。
processargs() {
(( "$#" )) && printf -- '-Z\0%s\0' "$@"
}
array=('' 1 ' x y ' $'multiline\ntext')
mapfile -d '' arrayWithZ < <(processargs "${array[@]}")
为了进行测试,我们使用内置的declare -p
打印结果数组arrayWithZ
的所有条目(手动插入换行符以提高可读性)。
$ declare -p arrayWithZ
declare -a arrayWithZ=(
[0]="-Z"
[1]=""
[2]="-Z"
[3]="1"
[4]="-Z"
[5]=" x y "
[6]="-Z"
[7]=$'multiline\ntext'
)
对于空数组,我们不插入任何-Z
。如果为array=()
,则为arrayWithZ=()
。
eval
,尤其是bash
<4.4 如果不需要显式数组arrayWithZ
,则可以使用以下技巧。即使在这种情况下eval
应该是安全的,我还是建议不要使用它-也许我确实监督了一些事情。但是,当您陷入bash
<4.4时,此黑客可能会很有用,因为不再需要mapfile -d
。
processargs() {
(( "$#" )) && printf -- '-Z %q ' "$@"
}
array=('' 1 ' x y ' $'multiline\ntext')
eval "yourCommand $(processargs "${array[@]}")"