如果我在Bash中有一个这样的数组:

FOO=( a b c )

如何用逗号连接元素?例如,生成a b c。


当前回答

这个特别适用于busybox的sh和$@:

$ FOO=(a b c)
$ printf '%s\n' "${FOO[@]}" | paste -sd,
a,b,c

Or:

join_by() {
    local d=$1
    shift
    printf '%s\n' "$@" | paste -sd "$d"
}
join_by , "${FOO[@]}"  # a,b,c

其他回答

$ set a 'b c' d

$ history -p "$@" | paste -sd,
a,b c,d

支持多字符分隔符的100%纯Bash函数是:

function join_by {
  local d=${1-} f=${2-}
  if shift 2; then
    printf %s "$f" "${@/#/$d}"
  fi
}

例如,

join_by , a b c #a,b,c
join_by ' , ' a b c #a , b , c
join_by ')|(' a b c #a)|(b)|(c
join_by ' %s ' a b c #a %s b %s c
join_by $'\n' a b c #a<newline>b<newline>c
join_by - a b c #a-b-c
join_by '\' a b c #a\b\c
join_by '-n' '-e' '-E' '-n' #-e-n-E-n-n
join_by , #
join_by , a #a

上面的代码基于@gniourf_gniourf、@AdamKatz、@MattCowell和@x-yuri的想法。它使用选项errexit (set -e)和nounset (set -u)。

或者,一个更简单的只支持单个字符分隔符的函数是:

function join_by { local IFS="$1"; shift; echo "$*"; }

例如,

join_by , a "b c" d #a,b c,d
join_by / var local tmp #var/local/tmp
join_by , "${FOO[@]}" #a,b,c

这个解决方案是基于Pascal Pilz最初的建议。

前面提出的解决方案的详细说明可以在“如何在bash脚本中连接()数组元素”中找到,这是meleu在dev.to上发表的一篇文章。

也许迟到了,但这对我来说是可行的:

function joinArray() {
  local delimiter="${1}"
  local output="${2}"
  for param in ${@:3}; do
    output="${output}${delimiter}${param}"
  done

  echo "${output}"
}

如果你在循环中构建数组,这里有一个简单的方法:

arr=()
for x in $(some_cmd); do
   arr+=($x,)
done
arr[-1]=${arr[-1]%,}
echo ${arr[*]}

这里有一个单行,有点奇怪,但适用于多字符分隔符,并支持任何值(包括包含空格或任何东西):

ar=(abc "foo bar" 456)
delim=" | "
printf "%s\n$delim\n" "${ar[@]}" | head -n-1 | paste -sd ''

这将在控制台显示为

abc | foo bar | 456

注意:注意一些解决方案是如何使用${ar[*]}和${ar[@]}的printf ?

带@的使用printf特性,通过重复格式模板来支持多个参数。

带*的不应该使用。它们实际上不需要打印,而是依赖于操作字段分隔符和bash的单词展开。这些方法同样适用于echo、cat等——这些解决方案可能使用printf,因为作者并不真正理解他们在做什么……