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.