如何将 bash 数组变量转换为用换行符分隔的字符串?

ACy*_*lic 65 bash newlines

我想将一个 bash 数组变量写到一个文件中,每个元素都在一个新行上。我可以用 for 循环来做到这一点,但是还有另一种(更干净的)方法来连接元素\n吗?

che*_*ner 83

这是一种利用 bash 参数扩展及其IFS特殊变量的方法。

$ System=('s1' 's2' 's3' 's4 4 4')
$ ( IFS=$'\n'; echo "${System[*]}" )
Run Code Online (Sandbox Code Playgroud)

我们使用子shell来避免覆盖IFS当前环境中的值。在该子 shell 中,我们然后修改 的值,IFS以便第一个字符是换行符(使用$'...'引号)。最后,我们使用参数扩展将数组的内容打印为单个单词;每个元素由 的第一个字符分隔IFS

要捕获到变量:

$ var=$( IFS=$'\n'; echo "${System[*]}" )
Run Code Online (Sandbox Code Playgroud)

如果您的 bash 足够新(4.2 或更高版本),您可以(并且应该)仍然使用printf以下-v选项:

$ printf -v var "%s\n" "${System[@]}"
Run Code Online (Sandbox Code Playgroud)

在任何一种情况下,您可能都不希望var. 要删除它:

$ var=${var%?}    # Remove the final character of var
Run Code Online (Sandbox Code Playgroud)

  • 最后一个例子不应该是 `var=${var%?}` 吗?这不是正则表达式,因此`.` 将只匹配一个句点字符。 (2认同)
  • `var=$( .. )` 自动修剪尾随换行符;`printf -v var` 没有 (2认同)

rus*_*ush 32

您可以使用printf在其自己的行上打印每个数组项:

 $ System=('s1' 's2' 's3' 's4 4 4')
 $ printf "%s\n"  "${System[@]}"
s1
s2
s3
s4 4 4
Run Code Online (Sandbox Code Playgroud)


Meo*_*eow 9

awk -v sep='\n' 'BEGIN{ORS=OFS="";for(i=1;i<ARGC;i++){print ARGV[i],ARGC-i-1?sep:""}}' "${arr[@]}"
Run Code Online (Sandbox Code Playgroud)

或者

perl -le 'print join "\n",@ARGV' "${arr[@]}"
Run Code Online (Sandbox Code Playgroud)

或者

python -c 'import sys;print "\n".join(sys.argv[1:])' "${arr[@]}"
Run Code Online (Sandbox Code Playgroud)

或者

sh -c 'IFS=$'\''\n'\'';echo "$*"' '' "${arr[@]}"
Run Code Online (Sandbox Code Playgroud)

或者

lua <(echo 'print(table.concat(arg,"\n"))') "${arr[@]}"
Run Code Online (Sandbox Code Playgroud)

或者

tclsh <(echo 'puts [join $argv "\n"]') "${arr[@]}"
Run Code Online (Sandbox Code Playgroud)

或者

php -r 'echo implode("\n",array_slice($argv,1));' -- "${arr[@]}"
Run Code Online (Sandbox Code Playgroud)

或者

ruby -e 'puts ARGV.join("\n")' "${arr[@]}"
Run Code Online (Sandbox Code Playgroud)

到目前为止,我只能提醒这些。