How does splitting string to array by 'read' with IFS word separator in bash generated extra space element?

一世执手 提交于 2019-12-13 15:51:08

问题


With only one character for IFS, it works fine:

shell@kernel: ~> l="2.4.3"; IFS="." read -a la <<< "$l"; for ((i = 0; i < ${#la[@]}; ++i)) do echo ${la[$i]}; done;
2
4
3

While there are two characters for IFS, extra space element generated

shell@kernel: ~> l="2->4->3"; IFS="->" read -a la <<< "$l"; for ((i = 0; i < ${#la[@]}; ++i)) do echo ${la[$i]}; done;
2

4

3
shell@kernel: ~> l="2..4..3"; IFS=".." read -a la <<< "$l"; for ((i = 0; i < ${#la[@]}; ++i)) do echo ${la[$i]}; done;
2

4

3

How can I get rid of the extra space element in the array?


回答1:


Continuing from the comment, you can either test for an empty element before storing the value in the array, or you can deal with the empty value when you echo it. Frankly, its simpler to do the latter, e.g.

l="2->4->3"; IFS="->" read -a la <<< "$l"; \
for ((i = 0; i < ${#la[@]}; ++i)) do \
[ -n "${la[i]}" ] && echo ${la[$i]}; done

Output

2
4
3



回答2:


i would just use sed to replace the separator

see, reusing your script + sed

bash$ l="2->4->3"
bash$ read -a la <<< "$(echo $l | sed 's/->/ /g')"
bash$ for ((i = 0; i < ${#la[@]}; ++i)) do echo ${la[$i]}; done
2
4
3

but I think I would do it entirely differently

bash$ l="2->4->3"
bash$ for x in `echo $l | sed 's/->/ /g'`; do echo $x; done
2
4
3

hope this helps




回答3:


You could transform the separator -> into a single character with:

l="2->4->3"

IFS="-" read -a la <<< "${l//->/-}"

printf '%s' "${la[@]}"

If there is the risk that the string may contain additional - then use a character that is improbable that will be in the string:

IFS="┵" read -a la <<< "${l//->/┵}"


来源:https://stackoverflow.com/questions/40011867/how-does-splitting-string-to-array-by-read-with-ifs-word-separator-in-bash-gen

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!