Comparando arquivos de texto usando Bash e AWK

Comparando arquivos de texto usando Bash e AWK

Tenho dois arquivos de texto e quero comparar seus valores correspondentes de acordo com suas linhas e colunas. Ao comparar, quero verificar se os valores são iguais e repetir se os valores são iguais ou não. Aqui estão os arquivos:

file1.txt

Name  Col1  Col2  Col3  
-----------------------
row1  1     4     7        
row2  2     5     8         
row3  3     6     9   

file2.txt

Name  Col1  Col2  Col3  
-----------------------
row2  1     4     11        
row1  2     5     12

Aqui estão as restrições:

  • compare apenas as linhas que existem (ou seja, como a linha3 existe no arquivo1.txt, mas não no arquivo2.txt, nenhuma comparação é necessária)
  • Deve usarAWK
  • As linhas podem estar fora de ordem nos arquivos
  • Não há matrizes duplas, pois minha versão do AWK não oferece suporte

Estou pensando em algo assim:

awk 'NR>2 {next}
{
    for (i=2;i<NR;i++)              #For each row of file1.txt
    {     
        for(j=1;i<NF;j++)           #For each column of file1.txt
        {
             // Check if row and column of file1.txt is equal to row and column of file2.txt.
        } 
    }
}
' file1.txt file2.txt

Como você compara valores de dois arquivos de texto diferentes? Deixe-me saber se mais explicações são necessárias.

Tudo o que peço é uma estrutura geral usando AWK. Espero que eu possa descobrir o resto.

Responder1

Este gera as linhas do arquivo2 onde o nome está em ambos os arquivos, mas qualquer um dos valores é diferente

awk 'NR==FNR {f1[$1]=$0; next} $1 in f1 && $0 != f1[$1]' file1.txt file2.txt 
row2  1     4     11        
row1  2     5     12

Percebi que mesmo uma diferença nos espaços em branco dará resultados falsos. Podemos "normalizar" as linhas:

awk '
    NR==FNR  {$1=$1; f1[$1]=$0; next} 
    $1 in f1 {$1=$1; if ($0 != f1[$1]) print}
' file1.txt file2.txt 
row2 1 4 11
row1 2 5 12

Responder2

Há muitas maneiras de fazer isso, aqui está uma solução com gawk 4.x:

$ awk '
    FNR < 2 { next }
    FNR == NR {
        for (i = 2; i <= NF; i++) {
            a[$1][i] = $i;
        }
        next;
    }
    ($1 in a) {
      for (i = 2; i <= NF; i++) {
          if (a[$1][i] == $i) {
              printf("%s->Col%d: Equal\n", $1, i-1);
          } else {
              printf("%s->Col%d: Not Equal\n", $1, i-1);
          }
       }
  }
' file1.txt file2.txt
row2->Col1: Not Equal
row2->Col2: Not Equal
row2->Col3: Not Equal
row1->Col1: Not Equal
row1->Col2: Not Equal
row1->Col3: Not Equal

Explicação

  • FNR < 2 { next }: pule as duas primeiras linhas
  • FNR == NR: só é verdade quando processamos o primeiro arquivo. Salvamos o valor de cada coluna em array associativo a, com form a[ROW][COLUMN].
  • ($1 in a): verifique se a linha do arquivo2 existia no arquivo1. Se for verdade, percorremos todos os valores da coluna e comparamos com o valor no arquivo1.

Com gawkuma versão mais antiga, você pode tentar:

$ awk '
    FNR < 2 { next }
    FNR == NR {
        for (i = 2; i <= NF; i++) {
            a[i,$1] = $i;
            b[$1];
        }
        next;
    }
    ($1 in b) {
      for (i = 2; i <= NF; i++) {
          if (a[i,$1] == $i) {
              printf("%s->Col%d: Equal\n", $1, i-1);
          } else {
              printf("%s->Col%d: Not Equal\n", $1, i-1);
          }
       }
  }
' file1.txt file2.txt

Responder3

Experimente isso dentro do loop for interno:

awk ' {
      if(i == j)
           print "Same value";
      else
           print "Not the same";
       }'

Esta é uma declaração condicional simples que pode ajudar, mas pode precisar de alguns ajustes adicionais na comparação de dois arquivos de texto diferentes...

informação relacionada