有什么方法可以在 shell 脚本中找到两个字符串之间的 Ascii 差异。最初应该检查第一个字符,如果第一个字母相同,则应该检查两者中的第二个。就像 C 的 strcmp 函数一样。
strcmp 返回第一个不匹配字符的 ascii 值的差异。即 strcmp("hello","world") 是 -15 而 strcmp("hello","Hello") 是 32。希望你明白了。
您可以像这样获得两个字符的 ascii 值之间的差异:
(( $(printf %d \"$a) - $(printf %d \"$b)))
所以这应该工作:
strcmp() {
local diff
for ((i=0; i<=${#1}; ++i)); do
if ((diff=$(printf %d \""${1:i:1}") - $(printf %d \""${2:i:1}") ));
then echo $diff; return
fi
done
echo 0
}
如果一个字符串是另一个字符串的前缀,您没有指定值应该是什么;以上使用较短字符串的尾随 NUL 字符 (0) 来计算差异。
测试:
$ strcmp hello world
-15
$ strcmp hello Hello
32
$ strcmp abc def
-3
$ strcmp def abc
3
$ strcmp def dbc
3
$ strcmp def ddc
1
$ strcmp def dgc
-2
$ strcmp def dec
3
$ strcmp def de
102
$ strcmp de def
-102
$ strcmp def def
0
$ strcmp "a b c" "a bde"
-68
$ strcmp "a b c" "a b e"
-2
在 bash 中(因为你标记了它):
$ cat tst.sh
function strcmp() {
printf "%d\n" $(( $(printf "%d" "'${1:0:1}") - $(printf "%d" "'${2:0:1}")))
}
printf "strcmp(\"$1\",\"$2\") = %d\n" $(strcmp "$1" "$2")
$ ./tst.sh foo foo
strcmp("foo","foo") = 0
$ ./tst.sh foo bar
strcmp("foo","bar") = 4
$ ./tst.sh bar foo
strcmp("bar","foo") = -4
使用test
(这里称为括号内)进行词法比较。
[ 'bar' '<' 'foo' ] # returns true
[ 'bar' '>' 'foo' ] # returns false
[ 'bar' = 'foo' ] # returns false
你可以把一个小函数放在一起,有点模仿 C 的strcmp
函数:
function strcmp {
if [ $1 == $2 ]
then
return 0
elif [ $1 '<' $2 ]
then
return 2
fi
return 1
}
strcmp foo bar
echo $?
请记住,没有负返回值,因此您必须选择不寻常的返回值或设置一个变量。
以下功能完成工作,
strcmp()
{
arg1=$1
len=${#arg1}
arg2=$2
len1=${#arg2}
len1=$(($len1+1))
len=$(($len+1))
i=0
# echo $len - $len1
while [ $i -le $len ] || [ $i -le $len1 ];
do
tem1=${arg1:$i:1}
tem2=${arg2:$i:1}
# echo $tem1-$tem2;
val1=`echo $tem1 | tr -d "\n" | od -An -t dC`
val2=`echo $tem2 | tr -d "\n" | od -An -t dC`
res=$(($val1-$val2))
if [ $res -lt 0 ] ; then
# echo "Less $res"
break
elif [ $res -gt 0 ] ; then
#echo "Greater $res"
break
# else
# echo "Equal"
fi
i=$(($i+1))
# echo "i=$i"
done
echo $res
}
echo $(strcmp "Zefaop" "Zefat")
怎么样
$ diff <(echo "stackoverflow" ) <(echo "stackowerflow")
1c1
< stackoverflow
---
> stackowerflow
或者
$ cmp -bl <(echo "stackoverflow") <(echo "stackowerflow")
7 166 v 167 w
或者,遍历字符串中的所有字符:
#!/bin/bash
foo=string
for (( i=0; i<${#foo}; i++ )); do
echo ${foo:$i:1}
done
输出:
s
t
r
i
n
g
一些讨厌的人说 PHP 只不过是 C 的一个包装器,所以让我们使用它:
$ difference=$(php -r "echo strcmp('foo', 'far');")
$ echo $difference
14
PHP 安装在大多数系统上,或者可以轻松添加。没有定义strcmp
' 的返回值必须是等于、小于或大于 1 之外的任何值——因此代码在没有进一步测试的情况下不被视为可移植的(例如,当运行使用 gcc 以外的其他编译器编译的 PHP 时)。