bash字符串由空值上的分隔符分隔



我有一个类似LINE=foo,bar,,baz的变量

我试图用分隔符,使用两种不同的技术来分割它:

  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]=$'bazn')

在第三个元素的末尾有一个无关的换行符,因此是$'bazn'值,所以您必须处理它(不过请参阅注释中的讨论(。不确定它是从哪里来的。

最新更新