Comparar 2 arquivos delimitados por tabulação e diferenças de saída com o cabeçalho da coluna

4

Gostaria de comparar dois arquivos semelhantes em uma coluna comum. Os arquivos terão cabeçalhos idênticos.

file1.txt

mem_id      Date    Time    Building    
aa          bb      cc      dd
ee          ff      gg      hh
ii          jj      kk      ll

file2.txt

mem_id      Date    Time    Building    
aa          bb      cc      dd
ee          ff      2g      hh
ii          jj      kk      2l

Command

awk 'NR==FNR{for(i=1;i<=NF;i++){A[i,NR]=$i}next} {for(i=1;i<=NF;i++){if(A[i,FNR]!=$i)\ 
{print "ID#-"$1": Column",i"- File1.txt value=",A[i,FNR]" / File2.txt value= "$i}}}'\ 
file1.txt file2.txt

Current Output

ID#-ee: Column 3- File1.txt value= gg / File2.txt value= 2g
ID#-ii: Column 4- File1.txt value= ll / File2.txt value= 2l

Desired Output

mem_id#-ee: Time- file1.txt value= gg / file2.txt value= 2g
mem_id#-ii: Building- file1.txt value= ll / file2.txt value= 2l 

Estou muito perto. Mas eu gostaria de ajuda com algumas melhorias.

1- Gostaria de substituir a “Coluna 3” e a “Coluna 4” pelo cabeçalho da coluna (Tempo, Edifício, o que for)

2- Gostaria de reunir dinamicamente os nomes dos arquivos na saída e não precisar adicioná-los como parte do comando (para torná-lo universal)

3- Eu gostaria desse script.

Qualquer ajuda seria apreciada.

    
por cmart2112 04.09.2014 / 21:24

2 respostas

2

Usando awk :

awk '
NR==1 { 
  for (i=1; i<=NF; i++)
    header[i] = $i
}
NR==FNR {
  for (i=1; i<=NF; i++) {
    A[i,NR] = $i
  }
  next
}
{
  for (i=1; i<=NF; i++)
    if (A[i,FNR] != $i)
      print "ID#-" $1 ": " header[i] "- " ARGV[1] " value= ", A[i,FNR]" / " ARGV[2] " value= "$i
}' file1.txt file2.txt

Saída:

ID#-ee: Time- file1.txt value=  gg / file2.txt value= 2g
ID#-ii: Building- file1.txt value=  ll / file2.txt value= 2l
    
por 05.09.2014 / 10:02
2

Aqui está um script que acho que funciona:

#! /bin/bash

FILE1=$1
FILE2=$2

[[ -z $FILE1 || -z $FILE2 ]] && echo "USAGE: $0 FILE1 FILE2" && exit 1

join -j 1 $FILE1 $FILE2 | 
awk '
NR == 1 { for (i = 1; i <= NF; i++) { header[i] = $i; }; NCOLS = (NF - 1)/2; } 
NR > 1 { for (i = 2; i <= NCOLS + 1; i++) { if ($i != $(i+NCOLS)) {print header[1]"#-"$1": "header[i]"- '$FILE1' value=",$i" / '$FILE2' value= "$(i+NCOLS) } } }
'

Eu apliquei um join nos arquivos para que eu possa leia-os de uma só vez.

Com NR == 1 , estou lendo na primeira linha para uma matriz (para que eu possa reutilizá-los mais tarde.

Como usei join , se os dois arquivos tiverem colunas n , a saída combinada terá 2n-1 colunas (as colunas usadas para união são mescladas). Então, eu salvo o número de colunas (descontando a coluna comum) para NCOLS .

    
por 04.09.2014 / 22:34