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

FOO=( a b c )

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


当前回答

awk -v sep=. 'BEGIN{ORS=OFS="";for(i=1;i<ARGC;i++){print ARGV[i],ARGC-i-1?sep:""}}' "${arr[@]}"

or

$ a=(1 "a b" 3)
$ b=$(IFS=, ; echo "${a[*]}")
$ echo $b
1,a b,3

其他回答

如果你想要连接的元素不是一个数组,而是一个空格分隔的字符串,你可以这样做:

foo="aa bb cc dd"
bar=`for i in $foo; do printf ",'%s'" $i; done`
bar=${bar:1}
echo $bar
    'aa','bb','cc','dd'

例如,我的用例是,在我的shell脚本中传递一些字符串,我需要使用这个来运行SQL查询:

./my_script "aa bb cc dd"

在my_script中,我需要做“SELECT * FROM表WHERE name In ('aa','bb','cc','dd')。那么上面的命令将是有用的。

通过重用@doesn't matters的解决方案,但通过避免${:1}的替换和中间变量的需要,使用了一个语句。

echo $(printf "%s," "${LIST[@]}" | cut -d "," -f 1-${#LIST[@]} )

printf有'格式字符串被重复使用,以满足参数。,这样字符串的连接就被记录下来了。然后诀窍是使用LIST长度来切割最后一个sperator,因为cut将只保留LIST的长度作为字段计数。

感谢@gniourf_gniourf对我迄今为止的最佳世界组合的详细评论。很抱歉发布的代码没有完全设计和测试。这是一个更好的尝试。

# join with separator
join_ws() { local d=$1 s=$2; shift 2 && printf %s "$s${@/#/$d}"; }

这种概念上的美是

(still) 100% pure bash ( thanks for explicitly pointing out that printf is a builtin as well. I wasn't aware about this before ... ) works with multi-character delimiters more compact and more complete and this time carefully thought over and long-term stress-tested with random substrings from shell scripts amongst others, covering use of shell special characters or control characters or no characters in both separator and / or parameters, and edge cases, and corner cases and other quibbles like no arguments at all. That doesn't guarantee there is no more bug, but it will be a little harder challenge to find one. BTW, even the currently top voted answers and related suffer from such things like that -e bug ...

附加的例子:

$ join_ws '' a b c
abc
$ join_ws ':' {1,7}{A..C}
1A:1B:1C:7A:7B:7C
$ join_ws -e -e
-e
$ join_ws $'\033[F' $'\n\n\n'  1.  2.  3.  $'\n\n\n\n'
3.
2.
1.
$ join_ws $ 
$

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

这与现有的解决方案并没有太大的不同,但它避免了使用单独的函数,不修改父shell中的IFS,并且都在一行中:

arr=(a b c)
printf '%s\n' "$(IFS=,; printf '%s' "${arr[*]}")"

导致

a,b,c

限制:分隔符不能超过一个字符。


可以化简为

(IFS=,; printf '%s' "${arr[*]}")

在这一点上,它基本上与Pascal的答案相同,但使用printf而不是echo,并将结果打印到stdout,而不是将其赋值给变量。