在Bash中使用IFS将字符串拆分为单个字符

3

我想把一个字符串分割成单独的字符。 例如,将temp="hello"变成"h", "e", "l", "l", "o"

我尝试使用IFS,因为这是我以前字符串拆分时使用的方法,并且希望保持脚本中的一致性。 IFS='' read h e l l o <<<"$temp"并不起作用。我做错了什么?


2
空白的 IFS 表示“不分割”。 - Etan Reisner
@EtanReisner 那么使用IFS进行空白分割就没有绝对的方法吗? - Krin123
我不知道任何使用IFS的“分割每个字符”的技巧。但你可以在循环中使用 read -n 1 -r char - Etan Reisner
@EtanReisner 好的,谢谢。 - Krin123
2个回答

6
你可以使用fold
arr=($(fold -w1 <<< "$temp"))

验证:

declare -p arr
declare -a arr='([0]="h" [1]="e" [2]="l" [3]="l" [4]="o")'

有没有一种方法可以使用IFS完成相同的事情? - Krin123
不要基于单个字符进行IFS分割。还有许多其他技巧可用,例如grep -o . <<< "$temp"或甚至是awk - anubhava

1
TL;DR: 这只是为了看看能否完成。像anubhava建议的那样使用fold;启动一个单独的进程是一个小代价,以避免不仅一个,而是两个使用eval

我实际上不会使用这个(我认为它是安全的,但我不能发誓,而且它很丑!),但你可以使用eval、大括号扩展和子字符串参数扩展来实现这一点。

$ temp=hello
$ arr=( $(eval echo $(eval echo \\\${temp:{0..${#temp}}:1})) )
$ printf '%s\n' "${arr[@]}"
h
e
l
l
o

这是如何工作的?非常细致。首先,shell会将${#temp}扩展为我们想要拆分其内容的变量长度。接下来,inner eval将字符串\${temp:{0..5}:1}转换为一组字符串${temp:0:1}${temp:1:1}等。最外层的eval执行参数扩展,每个参数扩展会从temp中产生一个字母,这些字母提供了数组的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接