2

有什么方法可以在 shell 脚本中找到两个字符串之间的 Ascii 差异。最初应该检查第一个字符,如果第一个字母相同,则应该检查两者中的第二个。就像 C 的 strcmp 函数一样。

strcmp 返回第一个不匹配字符的 ascii 值的差异。即 strcmp("hello","world") 是 -15 而 strcmp("hello","Hello") 是 32。希望你明白了。

4

6 回答 6

4

您可以像这样获得两个字符的 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
于 2013-09-25T22:23:46.143 回答
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
于 2013-09-25T22:32:46.953 回答
1

使用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 $?

请记住,没有负返回值,因此您必须选择不寻常的返回值或设置一个变量。

于 2013-09-25T21:06:05.773 回答
1

以下功能完成工作,

  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")
于 2013-09-26T10:40:33.627 回答
0

怎么样

$ 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
于 2013-09-25T21:02:02.123 回答
0

一些讨厌的人说 PHP 只不过是 C 的一个包装器,所以让我们使用它:

$ difference=$(php -r "echo strcmp('foo', 'far');")
$ echo $difference
14

PHP 安装在大多数系统上,或者可以轻松添加。没有定义strcmp' 的返回值必须是等于、小于或大于 1 之外的任何值——因此代码在没有进一步测试的情况下不被视为可移植的(例如,当运行使用 gcc 以外的其他编译器编译的 PHP 时)。

于 2013-09-25T21:33:53.387 回答