Как сравнить слишком похожие файлы - PullRequest
1 голос
/ 06 ноября 2019

У меня есть два таких текстовых файла:

строка похожа на => SITE.MACHINE.VARIABLE_NAME = VARIABLE_VALUE

CPM-NOMINAL.WAC12.CHRONO_SANSREPONSE_KEEPALIVE=0
CPM-NOMINAL.WAC13.CHRONO_SANSREPONSE_KEEPALIVE=0
DEMO-WEB.WAC7.XN_TCP_SERVICE_PDD_PORT=32099
...

Они уже отсортированы -u

Я должен выяснить, какие строки находятся в одном файле или в другом или были изменены (мне не нужны общие), например, команда sdiff . Но файлы имеют слишком похожие строки, которые создают ошибку diff.

Я думаю о diff с левой стороны от "=" и, если все в порядке, проверьте на правой стороне. Я ищу решение, которое печатает вывод, например, sdiff или что-то вроде.

требуемый вывод:

File1                                                         | File2
CPM-NOMINAL.WAC10.SAR_PARI_SUJET_A_COTES="1:0:1:1:0:0:0:0:0"  | CPM-NOMINAL.WAC10.SAR_PARI_SUJET_A_COTES="1:0:1:1:0:0:0:1:0"
CPM-NOMINAL.WAC12.CHRONO_SANSREPONSE_KEEPALIVE=1              | CPM-NOMINAL.WAC12.CHRONO_SANSREPONSE_KEEPALIVE=0
CPM-NOMINAL.WAC12.PARIS_SANSREPONSE_KEEPALIVE=1               | CPM-NOMINAL.WAC12.PARIS_SANSREPONSE_KEEPALIVE=0
CPM-NOMINAL.WAC12.PARIS_SANS_EMISSION_KEEPALIVE=1             | CPM-NOMINAL.WAC12.PARIS_SANS_EMISSION_KEEPALIVE=0
CPM-NOMINAL.WAC12.PROTOCOLE_PDD=2                             | CPM-NOMINAL.WAC12.PROTOCOLE_PDD=3
                                                              > CPM-NOMINAL.WAC7.SQL_PROC_INIT_XAPDD_MBN_TEST="p_initialiser"
CPM-NOMINAL.WAC8.FAIRE_VERIF_CHAINAGE=FALSE                   | CPM-NOMINAL.WAC8.FAIRE_VERIF_CHAINAGE=TRUE
DEMO-WEB.WAC7.XN_TCP_SERVICE_PDD_PORT=3201                    | DEMO-WEB.WAC7.XN_TCP_SERVICE_PDD_PORT=32099
DEMO-WEB.WAC7.XN_TCP_SERVICE_SAR_PORT=3201                    | DEMO-WEB.WAC7.XN_TCP_SERVICE_SAR_PORT=3204

Спасибо.

Ответы [ 2 ]

2 голосов
/ 06 ноября 2019

что-то подобное можно сделать с помощью join

$ join -a1 -a2 -e"---" -t= -o1.1,1.2,2.2,2.1 file1 file2 | column -ts=

CPM-NOMINAL.WAC10.SAR_PARI_SUJET_A_COTES         "1:0:1:1:0:0:0:0:0"             "1:0:1:1:0:0:0:1:0"  CPM-NOMINAL.WAC10.SAR_PARI_SUJET_A_COTES
CPM-NOMINAL.WAC12.CHRONO_SANSREPONSE_KEEPALIVE   1                               0                    CPM-NOMINAL.WAC12.CHRONO_SANSREPONSE_KEEPALIVE
CPM-NOMINAL.WAC12.PARIS_SANSREPONSE_KEEPALIVE    1                               0                    CPM-NOMINAL.WAC12.PARIS_SANSREPONSE_KEEPALIVE
CPM-NOMINAL.WAC12.PARIS_SANS_EMISSION_KEEPALIVE  1                               0                    CPM-NOMINAL.WAC12.PARIS_SANS_EMISSION_KEEPALIVE
CPM-NOMINAL.WAC12.PROTOCOLE_PDD                  2                               3                    CPM-NOMINAL.WAC12.PROTOCOLE_PDD
---                                              ---                             "p_initialiser"      CPM-NOMINAL.WAC7.SQL_PROC_INIT_XAPDD_MBN_TEST
CPM-NOMINAL.WAC8.FAIRE_VERIF_CHAINAGE            FALSE                           TRUE                 CPM-NOMINAL.WAC8.FAIRE_VERIF_CHAINAGE
DEMO-WEB.WAC7.XN_TCP_SERVICE_PDD_PORT            3201                            32099                DEMO-WEB.WAC7.XN_TCP_SERVICE_PDD_PORT
DEMO-WEB.WAC7.XN_TCP_SERVICE_SAR_PORT            3201                            3204                 DEMO-WEB.WAC7.XN_TCP_SERVICE_SAR_PORT

общие значения можно устранить с помощью трубопровода до awk '$2!=$3'

1 голос
/ 06 ноября 2019

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

key = value

Следующий список команд дает вам возможные ответы:

# lines common between file1 and file2
grep -F -f file1 file2
# lines in file2 not in file1
grep -v -F -f file1 file2
# changed key values from file1 to file2
cut -d'=' -f1 file1 | grep -F -f - <(grep -v -F -f file1 file2)
# keys in file1 but not in file2
cut -d'=' -f1 file1 | grep -v -F -f - file2
# keys in file2 but not in file1
cut -d'=' -f1 file2 | grep -v -F -f - file1

Или вы можете просто пойти на один простой awk,это не самый оптимизированный, но дает чистый вывод:

$ awk '
    BEGIN{FS=" *= *"}
    {key=$1;value=$2}
    (NR==FNR){a[key]=value; next}
    {b[key] = value }
    END {
       for (key in a) if (key in b) {
           print (a[key] == b[key] ? "COMM" : "DIFF"), key,"=",a[key],"<=>",b[key]
           delete a[key]
           delete b[key] 
       }
       for (key in a) {
           print "UNI1", key,"=",a[key]
       }
       for (key in b) {
           print "UNI2", key,"=",b[key]
       }
    }' file1 file2

Это даст некоторый вывод, похожий на

 COMM key1 = val1 <=> val1
 COMM key2 = val2 <=> val2
 DIFF key3 = val31 <=> val32      
 COMM key4 = val4 <=> val4
 UNI1 key5 = val5
 UNI2 key6 = val6      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...