【问题标题】:Bourne Shell compare two stringsBourne Shell 比较两个字符串
【发布时间】:2012-02-12 01:46:41
【问题描述】:

我需要在 Bourne shell 中比较两个相同固定长度的字符串。我需要将每个字符与相反字符串中的占位符进行比较,并找出有多少差异。有人对如何解决这个问题有任何建议吗?

我只是在计算差异的数量,即如果我比较 aab 和 aac,差异将是 1。

这也必须是 100% bourne。

【问题讨论】:

  • 您必须在 Bourne 而不是 Bash 中执行此操作?这是什么陈旧的系统?
  • @Mark Thomas:当 bourne 解决方案成功时,什么样的程序员会使用 bashisms?当有 zsh 时,谁在仍然使用 bash?看,这完全取决于您的偏好以及您的习惯或操作系统附带的内容。

标签: string scripting comparison sh


【解决方案1】:

如果您不介意创建临时文件,可以使用 cmp 方法。使用 Bourne shell,您可以做的事情非常有限。我要么使用 zsh/bash,要么如果 sh 是必不可少的,那就写一个 C 程序来做我想做的事。

如果每次都创建文件是不可能的,你可以创建fifos,但这真的很hackish和丑陋,不要这样做!

mkfifo cmp1
mkfifo cmp2
echo "abcd" > cmp1 &
echo "abce" > cmp2 &
DIFF_CHARS=`cmp -l cmp1 cmp2 | wc -l`

Bash 或任何现代 shell 中的进程替换使这变得微不足道,我肯定会尝试使用它。

【讨论】:

    【解决方案2】:

    有很多方法可以完成您所寻求的(据我所知),但以下 sn-p 代码应该可以帮助您入门:

    STRING1="test"
    STRING2="te5t"
    
    COUNT=0
    while [[ $COUNT -lt ${#STRING1}  ]]
    do
        POS=$(($COUNT + 1))
        char1=$(echo "${STRING1}" | cut -c $POS)
        char2=$(echo "${STRING2}" | cut -c $POS)
        if [ $char1 != $char2 ]; then
            echo $char1
            echo $char2
        fi
    
        COUNT=$(($COUNT + 1))
    done
    

    【讨论】:

    • 无论如何都知道在 Bourne shell 中拉出每个字符,抱歉不能有任何 bash。
    • 我已经更新了上面的代码示例。目前我只有 Bash 可用,但代码通过了 Bash 的 Bourne shell 兼容性。
    • 方括号在 Bourne shell 中不可用。
    【解决方案3】:

    这是一个非常纯正的 POSIX shell。它在 Dash(sh)和 BusyBox Ash(sh)中运行,并且不使用外部实用程序(除非您的 shell 没有内置 printf):

    #!/bin/sh
    string1="compare"
    string2="c0mp4r3"
    
    count=0
    while [ -n "$string1" ]
    do
        char1=$(printf "%1.1s" "$string1")
        char2=$(printf "%1.1s" "$string2")
        if [ "$char1" != "$char2" ]
        then
            count=$(($count + 1))
        fi
        string1=${string1#$char1}
        string2=${string2#$char2}
    done
    echo "There are $count differences"
    

    这将在 OBG1 上运行,Heirloom Bourne Shell:

    #!/usr/local/heirloom-bin/sh
    string1="compare"
    string2="c0mp4r3"
    
    count=0
    while [ -n "$string1" ]
    do
        char1=`printf "%1.1s" "$string1"`
        char2=`printf "%1.1s" "$string2"`
        if [ "$char1" != "$char2" ]
        then
            count=`expr $count + 1`
        fi
        string1=`echo "$string1" | cut -c 2-`
        string2=`echo "$string2" | cut -c 2-`
    done
    echo "There are $count differences"
    

    1Oldie But Goody 或 Original Bourne Granddaddy

    【讨论】:

      【解决方案4】:
      awk '{gsub(/[^[:alnum:]_[:blank:]]/, "", $0);for (i = 1; i <= NF; i++) {freq[$i]++}} END {for (word in freq){printf "%d\t%s\n", freq[word],word}}' {file} | sort -nr
      

      【讨论】:

        【解决方案5】:

        这可能是你想要的答案...Bash string difference

        使用cmp 比较两个字符串(diff 不会为您提供所需的详细程度。)

        【讨论】:

          【解决方案6】:

          出于教育目的,这是一个纯 Bourne(和 POSIX)解决方案,没有额外的分叉。使用COUNT=$((COUNT+1)),即使没有任何分叉,POSIX shell 也可以运行它:

          #!/bin/sh
          
          a=$1 b=$2
          
          COUNT=0
          while [ -n "$a" ]; do
            [ "${a%${a#?}}" != "${b%${b#?}}" ] && COUNT=`expr $COUNT + 1`
            a=${a#?} b=${b#?}
          done
          echo COUNT=$COUNT
          

          让我们在 OP 的字符串上运行它:

          $ ./x.sh aab aac
          COUNT=1
          

          【讨论】:

            猜你喜欢
            • 2010-09-16
            • 2015-12-21
            • 2020-09-05
            • 2017-07-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多