Text-Processing

如何比較 Unix 中的兩個 tsv 提取並使用鍵和標題列印差異?

  • August 30, 2021

我有兩個具有相同標題和結構的文件,第一列是一個鍵。

文件 1:

key    val1 val2 val3 val4 val5
Item1  10   12   44   88   22
Item2  33   33   43   77   22
Item3  28   44   55   22   11
Item4  12   55   55   14   44

文件2:

key    val1 val2 val3 val4 val5
Item1  10   11   44   99   22
Item2  33   33   43   77   22
Item3  28   44   55   22   11
Item4  12   55   55   14   00

正如您在上面的文件中註意到的那樣,文件中有兩個不同之處:

  • item1 的 val2 和 val4 不同
  • 第 4 項的 val5 不同

所以我想產生一個比較輸出,它應該告訴我哪個項目的哪些欄位不同。輸出應該類似於:

Item1: val2,val4
Item4: val5
awk -v ref=file1 '
   {
       getline refline <ref

       if (NR == 1) split(refline, head)

       nf = split(refline, a)

       for (i = 1; i <= nf; ++i)
           if ($i != a[i])
               diffcol[++n] = i

       if (n > 0) {
           $0 = a[1]

           for (i = 1; i <= n; ++i)
               $(i+1) = head[diffcol[i]]

           print
           n = 0
       }
   }' file2

這會將您file2與“參考文件”進行比較file1。from 的行file2通常由 讀取awk,而 from 的行file1是通過呼叫程式碼並用 分隔來顯式讀取getline的。awk``split

split(refline, head)塊將head數組設置為標題,從file1. 這僅對來自 的第一行輸入執行file2

第一個循環比較兩個文件之間的欄位以及任何不同並附加到diffcol數組的欄位的列號。

如果發現一個或多個差異,file1將輸出 的第一個欄位,然後輸出不同欄位的標題(來自file1)。

我編寫程式碼的方式,標題行和第一個欄位也受到比較,所以如果在第一個欄位中發現差異,你也會得到一行輸出,可能key在開始時行的(因為這是 中的第一個欄位的值file1)。

該程式碼不假定兩個文件中的列數相同。

鑑於您問題中的數據,您將從該程式碼中獲得以下輸出:

Item1 val2 val4
Item4 val5

引用自:https://unix.stackexchange.com/questions/666612