如果我在Bash中有一个这样的数组:
FOO=( a b c )
如何用逗号连接元素?例如,生成a b c。
如果我在Bash中有一个这样的数组:
FOO=( a b c )
如何用逗号连接元素?例如,生成a b c。
当前回答
通过重用@doesn't matters的解决方案,但通过避免${:1}的替换和中间变量的需要,使用了一个语句。
echo $(printf "%s," "${LIST[@]}" | cut -d "," -f 1-${#LIST[@]} )
printf有'格式字符串被重复使用,以满足参数。,这样字符串的连接就被记录下来了。然后诀窍是使用LIST长度来切割最后一个sperator,因为cut将只保留LIST的长度作为字段计数。
其他回答
下面是一个100%纯Bash函数,它可以完成这项工作:
join() {
# $1 is return variable name
# $2 is sep
# $3... are the elements to join
local retname=$1 sep=$2 ret=$3
shift 3 || shift $(($#))
printf -v "$retname" "%s" "$ret${@/#/$sep}"
}
看:
$ a=( one two "three three" four five )
$ join joineda " and " "${a[@]}"
$ echo "$joineda"
one and two and three three and four and five
$ join joinedb randomsep "only one element"
$ echo "$joinedb"
only one element
$ join joinedc randomsep
$ echo "$joinedc"
$ a=( $' stuff with\nnewlines\n' $'and trailing newlines\n\n' )
$ join joineda $'a sep with\nnewlines\n' "${a[@]}"
$ echo "$joineda"
stuff with
newlines
a sep with
newlines
and trailing newlines
$
这甚至保留了末尾的换行符,并且不需要一个子shell来获得函数的结果。如果你不喜欢printf -v(为什么你不喜欢它?)并传递一个变量名,你当然可以为返回的字符串使用一个全局变量:
join() {
# $1 is sep
# $2... are the elements to join
# return is in global variable join_ret
local sep=$1 IFS=
join_ret=$2
shift 2 || shift $(($#))
join_ret+="${*/#/$sep}"
}
如果你在循环中构建数组,这里有一个简单的方法:
arr=()
for x in $(some_cmd); do
arr+=($x,)
done
arr[-1]=${arr[-1]%,}
echo ${arr[*]}
我的尝试。
$ array=(one two "three four" five)
$ echo "${array[0]}$(printf " SEP %s" "${array[@]:1}")"
one SEP two SEP three four SEP five
使用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
这种方法处理值中的空格,但需要一个循环:
#!/bin/bash
FOO=( a b c )
BAR=""
for index in ${!FOO[*]}
do
BAR="$BAR,${FOO[$index]}"
done
echo ${BAR:1}