繁体   English   中英

bash 字符串由分隔符拆分空值

[英]bash string split by delimiter breaks on empty value

我有一个像LINE=foo,bar,,baz这样的变量

我尝试使用 2 种不同,技术将其与 delimiter 分开:

  1. array=(${LINE//,/ })
  2. array=($(echo "$LINE" | tr ',' '\n'))

echo ${array[2]}应该返回一个空值,但它返回baz (两者都将baz视为第三个值,而应该是第四个值。)

您可以使用read -a和备用分隔符来做到这一点:

IFS=, read -a array <<<"$LINE"

请注意,由于分配给IFSread命令的前缀,因此它仅适用于该命令,之后您不必将其设置回正常。 此外,与依赖于未引用变量的分词的那些不同,它不会尝试将任何看起来像文件名通配符的条目“扩展”到匹配文件的列表中。

演示:

$ LINE=foo,bar,,baz
$ IFS=, read -a array <<<"$LINE"
$ declare -p array
declare -a array='([0]="foo" [1]="bar" [2]="" [3]="baz")'

您依赖于标记之间的一系列空白作为分隔符,但当然,这将丢失任何空字符串。

作为一个有点粗略的解决方法,暂时覆盖 IFS:

oldIFS=$IFS
IFS=','
array=($LINE)
IFS=$oldIFS

演示: https://ideone.com/Dd1gUV

默认情况下,数组将所有“空白”字符视为分隔符。 如果您需要保留空值,则必须首先处理它们。

line='foo, ,bar,,baz'
line=${line//,,/,null,}
line=${line//,[[:blank:]],/,null,}
array=(${line//,/ })

$ echo "${array[@]}"
foo null bar null baz

$ echo "${array[@]//null/ }"
foo   bar   baz

您可以使用mapfile (或readarray ,同样的事情):

$ LINE=foo,bar,,baz
$ declare -a PARTS
$ mapfile -t -d, PARTS <<<"$LINE"
$ declare -p PARTS
declare -a PARTS=([0]="foo" [1]="bar" [2]="" [3]=$'baz\n')

在第三个元素的末尾有一个无关的换行符,因此是$'baz\n'值,所以你必须处理它(但请参阅评论中的讨论)。 不确定它来自哪里。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM