Bourne Shell сравнивает две строки - PullRequest
1 голос
/ 16 ноября 2010

Мне нужно сравнить две строки в оболочке Bourne одинаковой фиксированной длины.Мне нужно сравнить каждый символ с заполнителем в противоположной строке и выяснить, сколько существует различий.У кого-нибудь есть какие-либо предложения о том, как это сделать?

Я просто придумаю способ определения количества различий, т.е. если бы я сравнивал aab и aac, различия были бы равны 1.

Это такжедолжен быть 100% борн.

Ответы [ 6 ]

1 голос
/ 11 февраля 2012
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
1 голос
/ 16 ноября 2010

Это довольно чистая оболочка POSIX. Он работает в Dash (как sh) и BusyBox Ash (как sh) и не использует никаких внешних утилит (если ваша оболочка не имеет встроенной 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"

Это будет работать на OBG 1 , Оболочка Борн реликвии :

#!/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"

1 Олди Бат Гуди или Оригинал Bourne Granddaddy

1 голос
/ 16 ноября 2010

Если вы не против создания временных файлов, вы можете использовать метод cmp. С оболочкой Bourne вы довольно ограничены в том, что вы можете сделать. Я бы либо использовал zsh / bash, либо, если sh был необходим, написал бы программу на С, которая делала то, что я хочу.

Если о создании файлов каждый раз не может быть и речи, вы могли бы создать fifo, но это действительно ужасно и уродливо, не делайте этого!

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

Подстановка процессов в Bash или любой современной оболочке делает это тривиальным, и я определенно попытался бы использовать это.

1 голос
/ 16 ноября 2010

Есть довольно много способов выполнить то, что вы ищете (о чем я знаю), но следующий фрагмент кода должен вас начать:

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
0 голосов
/ 29 августа 2011

Для образовательных целей, это чисто решение Bourne (и POSIX), без дополнительных вилок.Оболочки POSIX могут запускать это даже без каких-либо разветвлений с COUNT=$((COUNT+1)):

#!/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
0 голосов
/ 16 ноября 2010

Это, вероятно, тот ответ, который вы хотите ... Разница строк в Bash

Использование cmp для сравнения двух строк (diff не даст вам требуемый уровень детализации.)

...