使用fold 而不是cut,您可以轻松地将外部命令的数量从每个字符一个减少到一个整个字符串:
#!/bin/sh
lizards='geckos,anoles'
echo "$lizards" | fold -w 1
我想不出纯粹使用内置函数的好方法。但我确实想到了一个丑陋的方法:
#!/bin/sh
lizards='geckos,anoles'
string_length="${#lizards}"
# Initialize j to length string_length-1 filled with ?'s and k to empty
i=1
j=
k=
while [ "$i" -lt "$string_length" ]; do
j="?$j"
i="$(( i + 1 ))"
done
i=0
# From here on, j contains string_length-i-1 ?'s and k contains i ?'s
while [ "$i" -lt "$string_length" ]; do
char="${lizards#$k}"
char="${char%$j}"
echo "$char" # or printf '%c\n' "$char"
j="${j#?}"
k="?$k"
i="$(( i + 1 ))"
done
要理解它,你必须首先理解${var#pattern} 和${var%pattern} 扩展,它们将$var 的开头(#)或结尾(%)与模式(glob-like,而不是正则表达式)并删除匹配的部分。 (这些取最短匹配,## 和 %% 取最长匹配,但这并不重要。)
因此,如果我想删除前 2 个字符的 $var,我使用 ${var#??}。如果我想删除最后 2 个字符,我使用 ${var%??}。所以我做了一个循环,每次使用可变数量的? 修剪两端。基本上它是这样做的:
char=${lizards#}; char=${char%????????????}; echo $char
char=${lizards#?}; char=${char%???????????}; echo $char
char=${lizards#??}; char=${char%??????????}; echo $char
char=${lizards#???}; char=${char%?????????}; echo $char
char=${lizards#????}; char=${char%????????}; echo $char
char=${lizards#?????}; char=${char%???????}; echo $char
char=${lizards#??????}; char=${char%??????}; echo $char
char=${lizards#???????}; char=${char%?????}; echo $char
char=${lizards#????????}; char=${char%????}; echo $char
char=${lizards#?????????}; char=${char%???}; echo $char
char=${lizards#??????????}; char=${char%??}; echo $char
char=${lizards#???????????}; char=${char%?}; echo $char
char=${lizards#????????????}; char=${char%}; echo $char
我特别喜欢编写j="${j#?}" 行,它使用${var#pattern} 构造从变量中删除一个字符,该字符将用作下一个${var%pattern} 构造中的模式。
实际上,我想我会使用fold。