在 bash 中为 $@ 添加前缀和后缀
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38558401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add prefix and suffix to $@ in bash
提问by Richard
How to add suffix and prefix to $@
?
如何添加后缀和前缀$@
?
If I do $PREFIX/$@/$SUFFIX
, I get the prefix and the suffix only in the first parameter.
如果我这样做$PREFIX/$@/$SUFFIX
,我只会在第一个参数中获得前缀和后缀。
回答by sjsam
I would use shell [ parameter expansion ]for this
我会用外壳 [参数扩展]此
$ set -- one two three
$ echo "$@"
one two three
$ set -- "${@/#/pre}" && set -- "${@/%/post}"
$ echo "$@"
preonepost pretwopost prethreepost
Notes
笔记
- The
#
matches the beginning - The
%
matches the end - Using double quotes around
${@}
considers each element as a separate word. so replacement happens for every positional parameter
- 在
#
开始处匹配 - 在
%
结束比赛 - 使用双引号
${@}
将每个元素视为一个单独的单词。所以每个位置参数都会发生替换
回答by John1024
Let's create a parameters for test purposes:
让我们为测试目的创建一个参数:
$ set -- one two three
$ echo "$@"
one two three
Now, let's use bash to add prefixes and suffixes:
现在,让我们使用 bash 添加前缀和后缀:
$ IFS=$'\n' a=($(printf "pre/%s/post\n" "$@"))
$ set -- "${a[@]}"
$ echo -- "$@"
pre/one/post pre/two/post pre/three/post
Limitations: (a) since this uses newline-separated strings, it won't work if your $@
contains newlines itself. In that case, there may be another choice for IFS
that would suffice. (b) This is subject to globbing. If either of these is an issue, see the more general solution below.
限制:(a) 由于这使用换行符分隔的字符串,如果您$@
包含换行符本身,它将不起作用。在这种情况下,可能有另一种选择IFS
就足够了。(b) 这受制于通配符。如果其中任何一个是问题,请参阅下面更通用的解决方案。
On the other hand, if the positional parameters do not contain whitespace, then no change to IFS
is needed.
另一方面,如果位置参数不包含空格,则不需要更改 to IFS
。
Also, if IFS
is changed, then one may want to save IFS
beforehand and restore afterward.
此外,如果IFS
更改了,则可能需要IFS
事先保存并在之后恢复。
More general solution
更通用的解决方案
If we don't want to make any assumptions about whitespace, we can modify "$@" with a loop:
如果我们不想对空格做任何假设,我们可以用循环修改“$@”:
$ a=(); for p in "$@"; do a+=("pre/$p/post"); done
$ set -- "${a[@]}"
$ echo "$@"
pre/one/post pre/two/post pre/three/post
回答by mklement0
Note: This is essentially a slightly more detailed version of sjam's answer.
注意:这本质上是sjam's answer 的一个更详细的版本。
John1024's answeris helpful, but:
John1024 的回答很有帮助,但是:
- requires a subshell(which involves a child process)
- can result in unwanted globbingapplied to the array elements.
- 需要一个子shell(它涉及一个子进程)
- 可能会导致不必要的通配符应用于数组元素。
Fortunately, Bash parameter expansioncan be applied to arraystoo, which avoids these issues:
幸运的是,Bash参数扩展也可以应用于数组,从而避免了这些问题:
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
This yields:
这产生:
declare -a a='([0]="PREFIXoneSUFFIX" [1]="PREFIXtwoSUFFIX")'
Note that double-quoting the array referencesis crucial to protect their elements from potential word-splittingand globbing(filename expansion) - both of which are instances of shell expansions.
需要注意的是双引号的数组引用是至关重要的,以防止潜在的要素字分裂和通配符(文件名扩展) -这两者都是实例shell扩展。