用$ @参数支持扩展

arc*_*rty 4 bash variable-expansion brace-expansion

假设我调用脚本与3个参数,a,abcxyz这样的$@包含这些三个参数.

假设我想调用write命令:

command fooa fooabc fooxyz bara barabc barxyz
Run Code Online (Sandbox Code Playgroud)

我怎么做到这一点?

我认为{foo,bar}$@{foo,bar}{$@}工作,因为大括号扩展在$@扩展之前发生.

Jon*_*ler 9

您可以使用:

command "${@/#/foo}" "${@/#/bar}"
Run Code Online (Sandbox Code Playgroud)

这使用了shell参数扩展的替代变体.将#匹配锚定到参数的开头.

$ set -- a abc xyz
$ echo command "${@/#/foo}" "${@/#/bar}"
command fooa fooabc fooxyz bara barabc barxyz
$
Run Code Online (Sandbox Code Playgroud)

有没有办法扩大规模{foo,bar,baz,...}$@或更大{foo,bar}{123,456}$@

是的,但你最终会使用数组:

$ set -- a abc xyz
$ args=( "$@" )
$ for prefix in foo bar baz who why; do prefixed1+=( "${args[@]/#/$prefix}" ); done
$ echo command "${prefixed1[@]}"
command fooa fooabc fooxyz bara barabc barxyz baza bazabc bazxyz whoa whoabc whoxyz whya whyabc whyxyz
$
Run Code Online (Sandbox Code Playgroud)

或者(注意你必须正确排序):

$ for prefix in 123 456; do prefixed1+=( "${args[@]/#/$prefix}" ); done
$ for prefix in foo bar; do prefixed2+=( "${prefixed1[@]/#/$prefix}" ); done
$ echo command "${prefixed2[@]}"
command foo123a foo123abc foo123xyz foo456a foo456abc foo456xyz bar123a bar123abc bar123xyz bar456a bar456abc bar456xyz
$
Run Code Online (Sandbox Code Playgroud)

请注意,这会保留参数中的空格:

$ unset prefixed1 prefixed2
$ set -- 'a b' 'x y z'
$ args=( "$@" )
$ for prefix in 'p p-' '123 456 '; do prefixed1+=( "${args[@]/#/$prefix}" ); done
$ echo command "${prefixed1[@]}"
command p p-a b p p-x y z 123 456 a b 123 456 x y z
$ for prefix in 'foo 1-' 'bar 2-'; do prefixed2+=( "${prefixed1[@]/#/$prefix}" ); done
$ echo command "${prefixed2[@]}"
command foo 1-p p-a b foo 1-p p-x y z foo 1-123 456 a b foo 1-123 456 x y z bar 2-p p-a b bar 2-p p-x y z bar 2-123 456 a b bar 2-123 456 x y z
$ printf "[%s]\n" "${prefixed2[@]}"
[foo 1-p p-a b]
[foo 1-p p-x y z]
[foo 1-123 456 a b]
[foo 1-123 456 x y z]
[bar 2-p p-a b]
[bar 2-p p-x y z]
[bar 2-123 456 a b]
[bar 2-123 456 x y z]
$
Run Code Online (Sandbox Code Playgroud)

第一个循环可能是:

for prefix in 'p p-' '123 456 '; do prefixed1+=( "${@/#/$prefix}" ); done
Run Code Online (Sandbox Code Playgroud)

不使用${args[@]}数组.