Shell-Script

需要使用awk根據具有多對一關係的兩列過濾數據

  • May 29, 2016

我有一個大文件,有 50s 列和 100K 行,由 | 分隔。現在 $ 2(col 2) has multiple type of $ 1(col 1) 值,這意味著 col 2 將被重複。所以我已經對文件進行了排序。我現在需要根據以下條件提取/過濾結果文件: $ 1 is column 1 $ 2 是第 2 列

之間存在一對多的關係 $ 2 and $ 1

條件1:當 $ 2 has both type of $ 1 (價值 $ 1 for $ 2 大於 8000 和小於 8000)然後選擇完整的行,其中 $ 1 < 8000 for the given $ 2(第2欄)

條件2:如果 $ 2 has only $ 1 >= 8000 然後選擇完整的行 $ 1 is the smallest for the given $ 2(第 2 列) 例如:源文件 在下面的範例中,我們有 3 種類型 $ 2 (1234,123 & 456) Now 1234 has 3 types of value in column 1 ( $ 1) 表示大於和小於 8000。因此,我們選擇了 $1<8000 的完整行。

對於 123 和 465,我們的第 1 列的值僅大於 8000($1>80000),因此我們選擇了最新的行(基於第 8 列的更高值)。

範例文件

 4000|1234||||||23
   5000|1234||||||40
   9000|1234||||||25
   10000|123|||||||21
   9000|123|||||||22
   22000|456|||||||27
   15000|456|||||||29

結果文件將具有:

4000|1234||||||23
5000|1234||||||40

9000|123|||||||22

15000|456|||||||29

請指教。提前致謝。

嘗試(你是你的文件)

sort -n -t\| -k2 -k1 &lt; u |
awk -F\| '$1 &lt; 8000 { a[$2]++ ; print } 
         $1 &gt;= 8000 { if ( !a[$2] && ( !e[$2] || e[$2]&lt;$8 ))  {u[$2]=$0;e[$2]=$8;} ; } 
         END { for ( i in u ) print u[i] ;}'

4000|1234||||||23
5000|1234||||||40
15000|456||||||29
9000|123||||||22

在哪裡

  • -t\|-F\|指示 sort 和 awk|用作分隔符
  • -k2 -k1: 按秒排序,然後是第一個欄位
  • |在排序行中應該是最後一個字元
  • $1 &lt; 8000 { a[$2]++ ; print }如果低於 8000,列印行並記住 $2 的值
  • $1 &gt;= 8000 { ... }如果高於,儲存最高值
  • END { for ( i in u ) print u[i] ;}退出時,轉儲所有值
  • 您可能需要重新排序。
  • 可以簡化第 2 行條件(通過在 {} 之外設置 if 條件)
  • 您的測試中的某些行有 9 個欄位。

請注意,命令可以是單行的

... | sort -n -t\| -k2 -k1  | awk -F\| '...'

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