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

FOO=( a b c )

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


当前回答

下面是大多数POSIX兼容shell支持的一个:

join_by() {
    # Usage:  join_by "||" a b c d
    local arg arr=() sep="$1"
    shift
    for arg in "$@"; do
        if [ 0 -lt "${#arr[@]}" ]; then
            arr+=("${sep}")
        fi
        arr+=("${arg}") || break
    done
    printf "%s" "${arr[@]}"
}

其他回答

使用perl实现多字符分隔符:

function join {
   perl -e '$s = shift @ARGV; print join($s, @ARGV);' "$@"; 
}

join ', ' a b c # a, b, c

或者在一行中:

perl -le 'print join(shift, @ARGV);' ', ' 1 2 3
1, 2, 3

下面是大多数POSIX兼容shell支持的一个:

join_by() {
    # Usage:  join_by "||" a b c d
    local arg arr=() sep="$1"
    shift
    for arg in "$@"; do
        if [ 0 -lt "${#arr[@]}" ]; then
            arr+=("${sep}")
        fi
        arr+=("${arg}") || break
    done
    printf "%s" "${arr[@]}"
}

这个简单的单字符分隔符解决方案需要非posix模式。在POSIX模式下,元素仍然正确地连接,但IFS=,赋值变成永久的。

IFS=, eval 'joined="${foo[*]}"'

使用#!bash头在默认情况下以非posix模式执行,但为了帮助确保脚本以非posix模式运行,请在脚本开头添加set +o posix或shop -uo posix。


对于多字符分隔符,我建议使用带有转义和索引技术的printf解决方案。

function join {
    local __sep=${2-} __temp
    printf -v __temp "${__sep//%/%%}%s" "${@:3}"
    printf -v "$1" %s "${__temp:${#__sep}}"
}

join joined ', ' "${foo[@]}"

Or

function join {
    printf -v __ "${1//%/%%}%s" "${@:2}"
    __=${__:${#1}}
}

join ', ' "${foo[@]}"
joined=$__

这是基于里卡多加利的回答和我的建议。

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

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

  echo "${output}"
}

x = $ {arr [*] / /,)

这是做这件事最短的方法。

的例子,

# ZSH:
arr=(1 "2 3" 4 5)
x=${"${arr[*]}"// /,}
echo $x  # output: 1,2,3,4,5

# ZSH/BASH:
arr=(1 "2 3" 4 5)
a=${arr[*]}
x=${a// /,}
echo $x  # output: 1,2,3,4,5