como usar o comando Diff ignorando o texto em uma linha e obtendo dados sem correspondência com base na condição

1

Estou tentando obter a saída abaixo com a entrada fornecida. Isso pode ser feito com o comando diff ? Eu estou tentando esta sintaxe mas não está funcionando:

diff -a  --suppress-common-lines a.txt b.txt

Aqui estão os dois arquivos de entrada:

Primeiro a.txt :

abc abc/d_4.1/efg 35 
xyz abc/d_4.1/efg 36
mno abc/d_4.1/efg 38

e b.txt :

abc abc/d_4/efg 35
xyz abc/d_4/efg 36
mno abc/d_4/efg 40

Eu preciso dessa saída (abaixo está o diff , independentemente de d_4.1 e d_4 em ambos os arquivos):

mno abc/d_4.1/efg 38
mno abc/d_4/efg  40
    
por brajkishore dubey 19.03.2017 / 18:22

2 respostas

1

O utilitário diff não tem uma opção para pular campos.

Eu tentei fazer isso funcionar com o & uniq. O pensamento abaixo funcionará, a coluna 2 estará ausente da saída.

$ cut -d/ -f1,3 file1 file2 |sort |uniq -u  #column 2 is skipped

Como uma solução mais correta, proponho o seguinte awk:

awk -F" |/" '{a=$1$2$4$5;seen[a]++;out[a]=$0}END{for (i in seen) if (seen[i]==1) print out[i]}' file1 file2

Eu uso o separador de campo espaço ou barra /, já que seus dados de entrada fornecidos incluem alguns espaços extras no final de cada linha.

Mesmo que seus dados reais não contenham espaço em branco extra, a solução acima ainda funcionará bem.

A lógica do awk é a seguinte: ele emula uniq -u, ignorando a coluna do meio ( /d_4/ ).
Apenas imprime todas as linhas exclusivas entre o arquivo1 e o arquivo2 (concatenado pelo awk).

Teste ( veja também o teste on-line )

cat file1 
cat file2 
echo "awk start:"
awk -F" |/" '{a=$1$2$4$5;seen[a]++;out[a]=$0}END{for (i in seen) if (seen[i]==1) print out[i]}' file1 file2
echo "awk end"

#Output
#file1            
abc abc/d_4.1/efg 35
xyz abc/d_4.1/efg 36 
mno abc/d_4.1/efg 38
#file2
abc abc/d_4/efg 35
xyz abc/d_4/efg 36 
mno abc/d_4/efg 40

awk start:      
mno abc/d_4/efg 40
mno abc/d_4.1/efg 38
awk end
    
por 20.03.2017 / 11:11
1

Usando awk e dividindo em / , esse código imprimirá as duas linhas quando o primeiro campo corresponder e o terceiro campo não.

Código:

#!/bin/awk -f
BEGIN { FS = OFS = "/" }

$1 in a2 && $3 != a2[$1] {
    print $1, a1[$1], a2[$1]
    print
}
{
    a1[$1] = $2
    a2[$1] = $3
}

Resultados:

$ awk -f test.awk file1 file2
mno abc/d_4.1/efg 38
mno abc/d_4/efg 40
    
por 19.03.2017 / 20:25