BashとAWKを使用したテキストファイルの比較

BashとAWKを使用したテキストファイルの比較

2つのテキストファイルがあり、行と列に基づいてその値を比較したいと思います。比較すると、値が等しいことを確認し、値が等しいかエコーすることを意味します。ファイルは次のようになります。

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

制限事項は次のとおりです。

  • 存在する行のみを比較します。つまり、row3はfile1.txtにありますが、file2.txtにはないため、比較は不要です。
  • 使用すべきAWK
  • ファイルの行が順序ではない可能性があります。
  • 私のAWKバージョンがサポートしていないので、二重配列はありません。

私は次のことを考えています:

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

2つの異なるテキストファイルの値を比較するには?さらに説明が必要な場合はお知らせください。

私が求めているのは、AWKの共通構成を使用することだけです。残りは把握できることを願っています。

答え1

これにより、両方のファイルに名前が存在しますが、値が異なるfile2の行が出力されます。

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

空白の違いでさえ、間違った結果をもたらす可能性があることに気づきました。次の行を「正規化」できます。

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

答え2

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

説明する

  • FNR < 2 { next }:最初の2行をスキップします。
  • FNR == NR: 最初のファイルを処理する場合のみ true です。各列の値を連想配列a形式で保存しますa[ROW][COLUMN]
  • ($1 in a):file2の行がfile1に存在することを確認してください。 trueの場合、すべての列の値を繰り返してfile1の値と比較します。

以前のgawkバージョンでは、次のことを試すことができます。

$ 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

答え3

forループ内で次のことを試してください。

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

以下は役に立つ簡単な条件文ですが、2つの異なるテキストファイルを比較して追加の調整が必要になる場合があります。

関連情報