如何为$@
添加后缀和前缀?
如果我$PREFIX/$@/$SUFFIX
,我只在第一个参数中获得前缀和后缀。
答案 0 :(得分:19)
我会将shell [ parameter expansion ]用于此
$ set -- one two three
$ echo "$@"
one two three
$ set -- "${@/#/pre}" && set -- "${@/%/post}"
$ echo "$@"
preonepost pretwopost prethreepost
备注强>
#
与开头%
与结尾${@}
周围使用双引号会将每个元素视为一个单独的单词。所以每个位置参数都要进行更换答案 1 :(得分:8)
让我们为测试目的创建一个参数:
$ set -- one two three
$ echo "$@"
one two three
现在,让我们使用bash添加前缀和后缀:
$ IFS=$'\n' a=($(printf "pre/%s/post\n" "$@"))
$ set -- "${a[@]}"
$ echo -- "$@"
pre/one/post pre/two/post pre/three/post
限制:(a)因为它使用换行符分隔字符串,如果$@
包含换行符,它将无法工作。在这种情况下,IFS
可能还有另一种选择就足够了。 (b)这受到全球化的影响。如果其中任何一个是问题,请参阅下面的更一般的解决方案。
另一方面,如果位置参数不包含空格,则不需要更改IFS
。
此外,如果更改IFS
,则可能需要事先保存IFS
并在之后恢复。
如果我们不想对空格做任何假设,我们可以修改" $ @"循环:
$ a=(); for p in "$@"; do a+=("pre/$p/post"); done
$ set -- "${a[@]}"
$ echo "$@"
pre/one/post pre/two/post pre/three/post
答案 2 :(得分:7)
注意:这基本上是this Amazon re-invent presentation的更详细版本。
sjam's answer很有帮助,但是:
幸运的是,Bash John1024's answer也可以应用于数组,这可以避免这些问题:
set -- 'one' 'two' # sample input array, which will be reflected in $@
# Copy $@ to new array ${a[@]}, adding a prefix to each element.
# `/#` replaces the string that follows, up to the next `/`,
# at the *start* of each element.
# In the absence of a string, the replacement string following
# the second `/` is unconditionally placed *before* each element.
a=( "${@/#/PREFIX}" )
# Add a suffix to each element of the resulting array ${a[@]}.
# `/%` replaces the string that follows, up to the next `/`,
# at the *end* of each element.
# In the absence of a string, the replacement string following
# the second `/` is unconditionally placed *after* each element.
a=( "${a[@]/%/SUFFIX}" )
# Print the resulting array.
declare -p a
这会产生:
declare -a a='([0]="PREFIXoneSUFFIX" [1]="PREFIXtwoSUFFIX")'
请注意,双引号数组引用对于保护其元素免受潜在的分词和 globbing (文件名扩展)至关重要 - 这两者都是parameter expansion的实例。