本文介绍了如何将数组转换为逗号分隔的字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组,正在像这样打印它:

I have an array and I am printing it like this:

echo "${data[*]}"

输出:

/QE-CI-RUN-71/workspace/QE-AU/57/testng-results_1.xml
/QE-CI-RUN-71/workspace/QE-AU/57/testng-results_2.xml

我想将上面的输出存储为逗号分隔的值.如何在Bash中实现这一目标?

I want to store the above output as a comma separated value. How can I achieve this in Bash?

数据数组是动态的,它可以具有任意数量的值.

The data array is dynamic, it may have any number of values.

推荐答案

有几种方法可以做到这一点:

There are a few ways to do this:

1. 直接与printf 加入(通过 Charles Duffy的评论)

printf -v joined '%s,' "${data[@]}"
echo "${joined%,}"

内置的printf隐式连接数组.您可以像下面的3a一样交互式打印,并用printf '%s,' "${data[@]}"单线打印,但是后面会留下逗号. (尽管POSIX无法处理其他数组类型,但您必须使用$@作为数组,该方法甚至可以在POSIX shell中使用.)

The printf builtin implicitly joins arrays. You could print interactively like 3a below with a one-liner reading printf '%s,' "${data[@]}", but you'd be left with a trailing comma. (This method even works in POSIX shell, though you'd have to use $@ as your array since POSIX can't handle other array types).

2. 更改$IFS字段分隔符(通过 chepner的答案)

join_arr() {
  local IFS="$1"
  shift
  echo "${data[$*]}"
}

join_arr , "${data[@]}"

这将在此函数的范围内重新定义字段分隔符,因此,当自动扩展$data数组时,它将使用所需的分隔符,而不是全局$IFS的第一个值或(如果为空或未定义)空间.

This redefines the field separator within just the scope of this function so when the $data array is automatically expanded, it uses the desired delimiter instead of the first value of the global $IFS or (if it's empty or undefined) space.

这可以在没有函数的情况下完成,但是保留$IFS有点麻烦: Charles Duffy指出临时重新分配后恢复IFS="$OLD_IFS"可能会评估为IFS="",但是如果以前未定义$IFS,则与unset IFS不同,尽管可以将它们分开,但由于使用了此功能,因此该方法更加清洁local来限制$IFS的范围.

This could be done without a function, but there's some nastiness about preserving $IFS: Charles Duffy notes that reverting IFS="$OLD_IFS" after temporarily reassigning it could evaluate to IFS="", but if $IFS was previously undefined, that's different from unset IFS and while it's possible to tease those apart, this functional approach is far cleaner thanks to its use of local to limit $IFS’s scope.

3a. 浏览其内容(并逐步打印)

3a. Loop through its contents (and print incrementally)

delim=""
for item in "${data[@]}"; do
  printf "%s" "$delim$item"
  delim=","
done
echo # add a newline

如果该循环中的其他代码涉及到外部调用(甚至是sleep 0.1),您实际上会逐个监视,这在交互式设置中会很有帮助.

If other code in that loop involves an external call (or even sleep 0.1), you'll actually watch this build piece by piece, which can be helpful in an interactive setting.

3b. 浏览其内容(并构建一个变量)

3b. Loop through its contents (and build a variable)

delim=""
joined=""
for item in "${data[@]}"; do
  joined="$joined$delim$item"
  delim=","
done
echo "$joined"

4. 将数组另存为字符串并对其进行替换(请注意,数组必须缺少空格*)

4. Save the array as a string and run replacement on it (note, the array must lack spaces*)

data_string="${data[*]}"
echo "${data_string//${IFS:0:1}/,}"

*仅在数组的任何项目中不存在的第一个字符(默认为空格)时,此方法才有效.

* This will only work if the first character of $IFS (space by default) does not exist in any of the array's items.

这将使用bash模式替换:${parameter//pattern/string}将$parameter中的每个pattern实例替换为string.在这种情况下,string是${IFS:0:1},$IFS的子字符串从一个字符的开头开始,然后在一个字符之后结束.

This uses bash pattern substitution: ${parameter//pattern/string} will replace each instance of pattern in $parameter with string. In this case, string is ${IFS:0:1}, the substring of $IFS starting at the beginning and ending after one character.

Z shell(zsh)可以在一个嵌套参数扩展中执行此操作:

Z shell (zsh) can do this in one nested parameter expansion:

echo "${${data[@]}//${IFS:0:1}/,}"

这篇关于如何将数组转换为逗号分隔的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 10:16