在bash中为$ @添加前缀和后缀

时间:2016-07-25 01:06:04

标签: bash

如何为$@添加后缀和前缀?

如果我$PREFIX/$@/$SUFFIX,我只在第一个参数中获得前缀和后缀。

3 个答案:

答案 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很有帮助,但是:

  • 需要子shell (涉及子进程
  • 会导致不需要的 globbing 应用于数组元素。

幸运的是,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的实例。