如果我在Bash中有一个这样的数组:
FOO=( a b c )
如何用逗号连接元素?例如,生成a b c。
如果我在Bash中有一个这样的数组:
FOO=( a b c )
如何用逗号连接元素?例如,生成a b c。
当前回答
感谢@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 $
$
其他回答
这种方法处理值中的空格,但需要一个循环:
#!/bin/bash
FOO=( a b c )
BAR=""
for index in ${!FOO[*]}
do
BAR="$BAR,${FOO[$index]}"
done
echo ${BAR:1}
如果你在循环中构建数组,这里有一个简单的方法:
arr=()
for x in $(some_cmd); do
arr+=($x,)
done
arr[-1]=${arr[-1]%,}
echo ${arr[*]}
结合所有最好的世界到目前为止与以下的想法。
# join with separator
join_ws() { local IFS=; local s="${*/#/$1}"; echo "${s#"$1$1$1"}"; }
这个小杰作是
100%纯bash(参数扩展,暂时不设置IFS,没有外部调用,没有printf…) 紧凑、完整和完美(适用于单字符和多字符限制符,适用于包含空格、换行符和其他shell特殊字符的限制符,适用于空分隔符) 高效(无子shell,无数组复制) 简单而愚蠢,但在某种程度上,也很漂亮,很有教育意义
例子:
$ join_ws , a b c
a,b,c
$ join_ws '' a b c
abc
$ join_ws $'\n' a b c
a
b
c
$ join_ws ' \/ ' A B C
A \/ B \/ C
通过重用@doesn't matters的解决方案,但通过避免${:1}的替换和中间变量的需要,使用了一个语句。
echo $(printf "%s," "${LIST[@]}" | cut -d "," -f 1-${#LIST[@]} )
printf有'格式字符串被重复使用,以满足参数。,这样字符串的连接就被记录下来了。然后诀窍是使用LIST长度来切割最后一个sperator,因为cut将只保留LIST的长度作为字段计数。
也许我遗漏了一些明显的东西,因为我是bash/zsh的新手,但在我看来,您根本不需要使用printf。没有它也不会变得很难看。
join() {
separator=$1
arr=$*
arr=${arr:2} # throw away separator and following space
arr=${arr// /$separator}
}
至少,到目前为止,它对我来说是有效的。
例如,加入\| *.sh,假设我在~目录下,输出utilities.sh|play.sh|foobar.sh。对我来说足够好了。
编辑:这基本上是Nil Geisweiller的答案,但推广到一个函数。