LINUX.ORG.RU

[bash] выявление различий в строках

 


0

1

Очередной добрый день всем Форумцам Линукс.орг. Обращаюсь за подсказкой. Вопрос в том что есть два текстовика с кодами. В одном текстовике оригинальный код, в другом текстовике куча буков и нужная нам строка с кодом. Эту строку я нахожу шаблоном grep -iE '^[0-1x]'. Что нужно? Оригинальный код и найденый сравнить по символьно и в лог записать сколько именно символов у нас отличается в % состовляющей. Допустим есть код 111001001101011110001101011101 (30 символов) и есть найденый код 1110хх0011хххх11ххх011х10хх101 (тоже 30 символов, но из них 12 отличаются). Скрипт должен их сравнить и выдать что код отличается на 12 символов и дальше мы делаем математические действия (bc) в итоге должны получить ответ 40%

Помогите разобраться как это все можно решить и с помощью чего? Больше всего интересует поиск различный символов и выдача правильного ответа Спасибо за внимание

bash не в кассу, пишем на zsh он из коробки умеет строки как массивы

a="string1"
b="string2"
for ((i=1;i<=${#a};i++));grep -q $k[i] <<< $b[$i] && ((matched++));echo $matсhed
zolden ★★★★★
()
Ответ на: комментарий от zolden

Не совсем понял данный скрипт, выдает синтаксическую ошибку на грепе. С zsh вообще не сталкивался. Методами Баша никак нельзя выполнить? Или может AWK? У diff не нашел нужной мне функции(((((((

arthur_s
() автор топика
#!/bin/sh
a1=111001001101011110001101011101
a2=1110хх0011хххх11ххх011х10хх101

echo $a1 | grep -Eo '.' > /dev/shm/a1
echo $a2 | grep -Eo '.' > /dev/shm/a2
dlen=`diff /dev/shm/a1 /dev/shm/a2 | grep -c '^>'`

echo "$dlen * 100 / ${#a1}"  | bc -l
40.0
sdio ★★★★★
()
Ответ на: комментарий от arthur_s

тебе лениво ставить zsh, мне лениво писать на баше...вот такая вот загогулина...
Можно и на баше и на awk и даже на sed.
Дело за малым - чуть-чуть подождать неленивых адептов упомянутых штук

zolden ★★★★★
()
Ответ на: комментарий от zolden

Та мне не лениво, просто я пока на ранней стадии изучения баша и мне пока тяжело во все это вникнуть, не хочу путаться, хочу ограничиться пока одним, а не всем сразу. В любом случае спасибо за отзывчивость.

arthur_s
() автор топика
Ответ на: комментарий от zolden

а ты всё не угомонишься, да

for ((i=1;i<=${#a};i++));[ $a[i] = $b[$i] ] && ((aha++));
echo "Строки одинаковы на $((${aha} * 100.0 / ${#a}))%"
zolden ★★★★★
()
Ответ на: комментарий от sdio

очень благодарен, скрипт работает, но есть одно НО - он не считает разницу в случае 111001001101011110001101011101 и 111001001101011110001101101011 где местами поменяны 4 цифры, это как то можно усвоить?

arthur_s
() автор топика
Ответ на: комментарий от arthur_s

хех, diff слишком умный :-)

#!/bin/sh

a1=111001001101011110001101011101
a2=111001001101011110001101101011

echo $a1 | grep -o '.' | nl > /dev/shm/a1
echo $a2 | grep -o '.' | nl > /dev/shm/a2

dlen=`diff /dev/shm/a1 /dev/shm/a2 | grep -c '^>'`

echo "$dlen * 100 / ${#a1}"  | bc -l
40.0

sdio ★★★★★
()
Ответ на: комментарий от sdio

Sdio, очень тебе благодарен, это то чего мне не хватало. СПС Огромное

arthur_s
() автор топика

кол-во отличающихся символов - как-то так :

a1="111001001101011110001101011101"
a2="1110хх0011хххх11ххх011х10хх101"
tmp=`mktemp`
echo $a1 > $tmp

num=`echo $a2 | cmp -l $tmp - | wc -l`

rm -f $tmp
echo "Отличаются $num символов"

если вместо «x» может быть любой символ (0 или 1) то добавить вызов grep перед «wc -l»

MKuznetsov ★★★★★
()
Ответ на: а ты всё не угомонишься, да от zolden

аналог на баше

#!/bin/bash

a1=111001001101011110001101011101
a2=111001001101011110001101101011
r=0

#строка --> массив
a=( `echo $a1 | sed 's/./& /g'` )
b=( `echo $a2 | sed 's/./& /g'` )

for ((i=0;i<${#a1};i++)) do
  [ ${a[i]} = ${b[$i]} ] || r=$(($r + 1))
done

echo "$r * 100 / ${#a1}" | bc -l
sdio ★★★★★
()
Ответ на: комментарий от MKuznetsov

да, cmp -l упрощает дело. (никогда man cmp толком не читал, использовал его всегда без параметров)

sdio ★★★★★
()
Ответ на: комментарий от sdio

Что-то считал что 4й баш полностью догнал zsh по функциям, но видимо таки нет...
Думаю можно обойтись без этих баш-стайл эмуляций массивов, а тупо посредством ${a:i:1} проходить по строке

zolden ★★★★★
()
Ответ на: комментарий от zolden

Может быть, я за развитием bash'a не слижу, всегда стараюсь писать с оглядкой на POSIX

sdio ★★★★★
()
Ответ на: комментарий от MKuznetsov

> echo $a2 | cmp -l $tmp - | wc -l

echo $a2 | sed 's/х/x/g' | cmp -l $tmp - | wc -l

Neksys ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.