[英]bash string split by delimiter breaks on empty value
我有一个像LINE=foo,bar,,baz
这样的变量
我尝试使用 2 种不同,
技术将其与 delimiter 分开:
array=(${LINE//,/ })
array=($(echo "$LINE" | tr ',' '\n'))
echo ${array[2]}
应该返回一个空值,但它返回baz (两者都将baz视为第三个值,而应该是第四个值。)
您可以使用read -a
和备用分隔符来做到这一点:
IFS=, read -a array <<<"$LINE"
请注意,由于分配给IFS
是read
命令的前缀,因此它仅适用于该命令,之后您不必将其设置回正常。 此外,与依赖于未引用变量的分词的那些不同,它不会尝试将任何看起来像文件名通配符的条目“扩展”到匹配文件的列表中。
演示:
$ 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
默认情况下,数组将所有“空白”字符视为分隔符。 如果您需要保留空值,则必须首先处理它们。
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.