我试图让我的 bash 脚本处理变量中的第一个字符并一直工作直到到达最后一个字符。这是我到目前为止所拥有的:
#!/bin/bash
echo Word?
read -r -p '' foo
# $foo is set to 'Antarctica' by user.
wordlength=${#foo}
$wordlength says 10, so start on character 1.
'A' is first letter received in $foo, so echo '{a,A}'
'n' is second letter received in $foo, so echo '{n,N}'
't' is third letter received in $foo, so echo '{t,T}'
'a' is fourth letter received in $foo, so echo '{a,A}'
........
'i' is eighth letter received in $foo, so echo '{i,I}'
'c' is ninth letter received in $foo, so echo '{c,C}'
'a' is tenth letter received in $foo, so echo '{a,A}'
这是用户端的样子:
Word?
南极洲
{a,A}{n,N}{t,T}{a,A}{r,R}{c,C}{t,T}{i,I}{c,C}{a,A}
这正是它会输出的内容。有人知道怎么做吗?
编辑:我想它们可以这样链接? $wordlength 是 10,所以从 1 开始,到 10。
if 1st letter of $foo is A, echo '{a,A}'
if 2st letter of $foo is n, echo '{n,N}'
.....
答案1
ksh93
要迭代orbash
或中字符串的每个字符zsh
:
string=whatever
for ((i = 0; i < ${#string}; i++)); do
printf '%s\n' "Character $((i + 1)): ${string: i:1}"
done
在zsh
(yash
除了yash
不支持for ((...))
语法之外相同),另请参阅:
for ((i = 1; i <= ${#string}; i++)); do
printf '%s\n' "Character $i: $string[i]"
done
或者使用s
(用于拆分)参数扩展标志以空字符串作为分隔符:
for c (${(s"")string}) something with "$c"
为了将字符映射到字符串,您可以使用如下case
构造:
case $c in
(A) s='{O.O}';;
(a) s='{q-p}';;
...
esac
或者关联数组:
zsh
:typeset -A map map=( A '{O.O}' a '{q-p}' ... ) s=$map[$c]
ksh93
/bash
:typeset -A map map=( [A]='{O.O}' [a]='{q-p}' ... ) s=${map[$c]}
可移植(使用标准sh
语法),您还可以这样做:
map='|A={O.O}|a={q-p}|...'
s=${map#*"|$c="}
s=${s%%"|"*}
(假设所有字符串都不包含|
字符)。
或者,您还可以调用适当的文本处理实用程序(使用 shell 调用命令,因为这就是它的设计目的,并且使用文本处理实用程序来处理文本)。
STRING=whatever awk -F= '{map[$1] = $2}
END {
s = ENVIRON["STRING"]
l = length(s)
for (i = 1; i <= l; i++) {
c = substr(s, i, 1)
print map[c]
}
}' << EOF
A={O.O}
a={q-p}
...
EOF
(但请注意,awk
like的某些实现mawk
仅支持单字节字符)。