Identificando a diferença em dois arquivos no unix

0

Eu tenho 2 arquivos rec1.txt e rec2.txt.

[gpadmin@subh ~]$cat ret1.txt
emcas_fin_bi=324 
emcas_fin_drr=3294   
emcas_fin_exp=887 
emcas_fin_optics=0
emcas_gbo_gs=3077

e

[gpadmin@subh ~]$ cat ret2.txt 
emcas_fin_bi=333 
emcas_fin_drr=5528 
emcas_fin_exp=1134 
emcas_fin_optics=0 
emcas_fin_revpro=0 
emcas_gbo_gs=3897

Estou fornecendo para comparar como: -

 [gpadmin@subh ~]$ diff -y ret1.txt ret2.txt  
emcas_fin_bi=324 | emcas_fin_bi=333  
emcas_fin_drr=3294 | emcas_fin_drr=5528
emcas_fin_exp=887 | emcas_fin_exp=1134
emcas_fin_optics=0 emcas_fin_optics=0
emcas_gbo_gs=3077 | emcas_fin_revpro=0 
                        >  emcas_gbo_gs=3897

Eu vejo que isso é uma saída errada da saída acima, já que emcas_gbo_gs é comum, mas aparece como nova palavra: -

emcas_gbo_gs=3077 | emcas_fin_revpro=0
               > emcas_gbo_gs=3897

Saída desejada: -

emcas_gbo_gs=3077 | emcas_gbo_gs=3897   
                      > emcas_fin_revpro=0
    
por Subhashis Dey 27.08.2018 / 00:22

1 resposta

0

Suponho que você esteja interessado em comparar linhas que seguem o padrão

key=value

e a ordem das chaves dentro de um determinado arquivo não importa realmente.

Como um dos seus arquivos contém espaços à direita, acho que é bom higienizar a entrada primeiro. A função auxiliar a seguir faz mais. Ele descarta as linhas sem = . Ele remove os principais caracteres de espaço em branco e os caracteres de espaço em branco à direita. Também remove os caracteres de espaço em branco vizinhos, = .

sanitize() { grep '=' "$1" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//; s/[[:space:]]*=[[:space:]]*/=/'; }

Outra função (usando substituição de processos , não compatível com POSIX)

prepare() { diff <(sanitize "$1") <(sanitize "$2") | grep '^[<|>]' | sort -k 2 | uniq -u -f 1; }

irá gerar diferenças. Use assim:

prepare ret1.txt ret2.txt

e a saída será:

< emcas_fin_bi=324
> emcas_fin_bi=333
< emcas_fin_drr=3294
> emcas_fin_drr=5528
> emcas_fin_exp=1134
< emcas_fin_exp=887
> emcas_fin_revpro=0
< emcas_gbo_gs=3077
> emcas_gbo_gs=3897

Não é a saída que você quer, mas é bastante analisável . Isso significa que você pode processá-lo ainda mais do jeito que quiser. Por exemplo. você pode usar awk e column para obter o formato desejado (ou pelo menos algo próximo a ele):

prepare ret1.txt ret2.txt | awk -F '[ =]' '
    { $1 == "<" ? L[$2]=$3 : R[$2]=$3 }
    END {
         for (key in L) if (key in R) print key"="L[key]"/|/"key"="R[key]
         for (key in L) if (! (key in R)) print key"="L[key]"/<"
         for (key in R) if (! (key in L)) print " />/"key"="R[key]
        }
    ' | column -s / -t

O resultado é:

emcas_fin_exp=887   |  emcas_fin_exp=1134
emcas_fin_bi=324    |  emcas_fin_bi=333
emcas_fin_drr=3294  |  emcas_fin_drr=5528
emcas_gbo_gs=3077   |  emcas_gbo_gs=3897
                    >  emcas_fin_revpro=0

Nota: testado no Debian GNU / Linux 9.

    
por 27.08.2018 / 09:24