簡體   English   中英

如果一列中的值存在於另一列中,則使用 awk 忽略/刪除 output 中的行

[英]if value from one column is present in another columns then ignore/delete the line in output using awk

我想看看 column2 值是否存在於 column3 中,反之亦然,如果這是真的,那么我想從 output 中刪除它。

樣本.txt

3   abc def
5   ghk lmn
8   opq abc
10  lmn rst
15  uvw xyz
4   bcd abc
89  ntz uhg

到目前為止我有

awk ' {
    x[$2]=$2
    y[$3]=$3
    if (!(($2 in y) ||( $3 in x)) )
    {
     print $1,$2,$3
    }


} ' sample.txt

我想要 output 如下。

15  uvw xyz
89  ntz uhg

我知道 awk 逐行讀取文件並且我的代碼不兼容,因為它不檢查尚未看到的未來數組索引。 因此報告第一次發生。 想看看這是否可以在 awk 中以更簡單的方式完成,因為我的真實日期集非常龐大(多達 500 萬行,400-500 兆字節)。 謝謝!

使用兩遍輸入文件的一個awk想法:

awk '

# 1st pass:

FNR==NR { seen[$2]++           # increment our seen counter for $2
          if ($2 != $3)        # do not increment seen[] if $2==$3
             seen[$3]++        # increment our seen counter for $3
          next
        }

# 2nd pass:

seen[$2] <= 1 &&               # if seen[] counts are <= 1 for both
seen[$3] <= 1                  # $2 and $3 then print current line
' sample.txt sample.txt

這會產生:

15  uvw xyz
89  ntz uhg

一遍又一遍地復制前 4 行,直到sample.txt包含約 400 萬行,然后運行此awk腳本,生成相同的 2 行 output,並在我的系統上花費約 3 秒(在低端 9xxx 上運行的 VM) i7).


另一個awk想法使用一些額外的 memory 但只需要一次通過輸入文件:

awk '
    { seen[$2]++
      if ($2 != $3)
         seen[$3]++
      if (seen[$2] <=1 && seen[$3] <= 1)
         lines[++c]=$0
    }
END { for (i=1;i<=c;i++) {
          split(lines[i],arr)
          if (seen[arr[1]] <= 1 && seen[arr[2]] <= 1)
             print lines[i]
      }
    }
' sample.txt

這也會產生:

15  uvw xyz
89  ntz uhg

這一個的性能將取決於唯一的 $2/$3 值的數量,因此必須分配/處理的 memory 的數量。 對於我的 400 萬行sample.txt (其中 400 萬行是重復行,因此很少使用額外的 memory),運行時間約為 1.7 秒......比 2 遍解決方案(~3 秒)好一點但是對於真實世界的數據(具有大量獨特的 $2/$3 值),我猜時間會更近一些。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM