在unix中按列比較文件

在unix中按列比較文件

我想比較具有相同行數和列數且記錄順序相同的兩個文件。只是想突出顯示列值中的差異(如果有)。

file A:

1,kolkata,19,ab

2,delhi,89,cd

3,bangalore,56,ef

file B:

1,kolkata,21,ab

2,mumbai,89,gh

3,bangalore,11,kl

考慮到列1作為主鍵,我們在其他列上存在差異。我想強調這些差異。

輸出格式可能是(不確定):

record_number,  columns_with_diff
1               3

2               2,4

3               3,4

可以diffcomm解決我的問題嗎?如果是,那麼確切的命令是什麼?

答案1

就這樣了。只是每行末尾額外的逗號存在一些樣式問題。

awk '
     BEGIN{ FS=","; ORS="" }

     { 
       # read line from secondary file
       getline aux < "file2"
       split(aux,f2,",")

       # print current line number
       print NR" "

       # process each field in current line
       for(i=1; i<=NF; i++) {
         if ($i!=f2[i]) {
           print i","
         }
       }
       print "\n"
     }
' file1

輸出:

1 3,
2 2,4,
3 3,4,

答案2

您可以使用以下方法更輕鬆地做到這一點perl

$ perl -F',' -anle '
    BEGIN{
        print "record_number,  columns_with_diff";
        $" = ",";
    }
    if (!defined($h{$.})) {
        @{$h{$.}}{0..$#F} = @F[0..$#F];
    } else {
        @diff =  grep { $h{$.}{$_} ne $F[$_] } 0..$#F;
        print "$.\t\t@{[map {$_+1} @diff]}";
    } 
    close ARGV if eof;
' file1 file2
record_number,  columns_with_diff
1       3
2       2,4
3       3,4

為此,您應該刪除輸入中的空白行。

解釋

  • BEGIN區塊中,我們只列印輸出的標題,然後將清單分隔符號設為,

  • @{$h{$.}}{0..$#F} = @F[0..$#F]:我們建立一個散列的雜湊,第一個散列的鍵是行號,每個子散列的鍵是字段索引減1,值是與該字段對應的值。

這裡我們使用哈希切片來快速將值分配給哈希的哈希。

如果你用Data::Dumper印 hash of hashes %h,你可以看到類似這樣的東西:

VAR1 = {
          '2' => {
                   '2' => '89',
                   '0' => '2',
                   '1' => 'delhi',
                   '3' => 'cd'
                 },
          '3' => {
                   '1' => 'bangalore',
                   '3' => 'ef',
                   '0' => '3',
                   '2' => '56'
                 },
          '1' => {
                   '3' => 'ab',
                   '1' => 'kolkata',
                   '0' => '1',
                   '2' => '19'
                 }
        };
  • 如果我們建立了%h( if (!defined($h{$.}))) - 表示我們完成了處理file1- 我們只需將目前行的每個欄位與 coresspond 值進行比較%h,將所有不同的索引儲存在 array 中@diffmap {$_+1} @diff恢復列號,因為數組索引從0開始,列號從1開始。

  • close ARGV if eof恢復$.計數器。

相關內容