Comparação de dados em 2 arquivos csv

2

Eu tenho 3 arquivos:

Em file1 tenho dados como este:

id,name,age
1,jj,60
2,kk,45
3,ss,56

Em file2 tenho dados como este:

id,name,age
1,jj,60
2,kk,44
3,ss,55
4,tt,66

Em file3 , tenho apenas um campo, por exemplo, id:

id
1
2
3

Agora quero comparar file1 & file2 para esses ID que estão em file3 .

O resultado deve ser assim:

id  file1   file2
2   age=45  age=44
3   age=56  age=55
    
por Anand 12.02.2018 / 09:09

2 respostas

2

Solução estendida paste + awk :

awk -F',' -v ids=$(paste -s -d'|' <(tail -n+2 file3)) \
'BEGIN{ OFS="\t"; print "id", ARGV[1], ARGV[2] }
 FNR==1{ next }
 NR==FNR{ if ($1 ~ "^("ids")$") a[$1$2]=$3; next }
 ($1$2 in a) && a[$1$2] != $3{ 
     printf "%d\tage=%d\tage=%d\n", $1, a[$1$2], $3 
 }' file1 file2

A saída:

id  file1   file2
2   age=45  age=44
3   age=56  age=55
    
por 12.02.2018 / 10:38
1

A resposta de Roman é boa e dá a saída exata que você pediu.

Se, no entanto, você somente precisasse dos dados brutos (ou seja, sem cabeçalhos CSV e sem a formatação bem impressa), você poderia usar paste + comm + grep + substituição de processos :

$ paste <(comm -1 -3 file1 file2) <(comm -2 -3 file1 file2) | 
    grep -f <(sed -e 's/^/^/; s/$/,/;' file3)
2,kk,44 2,kk,45
3,ss,55 3,ss,56

Explicação:

comm -1 -3 file1 file2 exibe as linhas exclusivas de file2 . comm -2 -3 file1 file2 gera as linhas exclusivas para file1 . A saída desses dois comandos é dada para paste por meio da substituição do processo e unidos.

A saída de

paste é então canalizada para o grep para produzir apenas as linhas que correspondem aos ids listados em file3 . A substituição de processos também é usada aqui para transformar as IDs listadas no arquivo3 em expressões regulares ancoradas que correspondem aos números de ID SOMENTE quando estão no início de uma linha e seguidas por uma vírgula.

Fazer algo assim seria útil se você quisesse / precisasse de um processamento adicional antes de imprimir bem a saída.

    
por 12.02.2018 / 13:00