Awk

過濾具有特定標題名稱並在列中包含“1”的行

  • October 21, 2017

我有一個包含許多列和行的大文件,如下所示:

A  B  C  D  E  F1  F2  F3  F4  F5
a1 b1 c1 d1 e1 0   0   1   0   1
a2 b2 c2 d2 e2 1   0   0   1   1
a3 b3 c3 d3 e3 1   1   0   0   1
....

A、B、C、D、E列包含一些資訊,F1-5列代表一些id。0 或 1 表示該 id 的 AE 資訊不存在/存在。

我想為每個 id 創建文件,而每個文件都包含 id 具有的 ABCDE 資訊。例如,F5 在前 3 行中有 3 個 1,所以

F5.txt:

A  B  C  D  E 
a1 b1 c1 d1 e1 
a2 b2 c2 d2 e2 
a3 b3 c3 d3 e3

F1 在前 3 行有兩個 1,所以

F1.txt:

A  B  C  D  E  
a2 b2 c2 d2 e2 
a3 b3 c3 d3 e3

如何使用 awk 過濾此文件並使用 id 名稱(F1、F2 …)創建新文件?

**AWK**解決方案:

awk 'NR==1{ split($0,h); columns=sprintf("%s %s %s %s %s",h[1],h[2],h[3],h[4],h[5]); next }
    { for (i=6;i<=NF;i++) 
          if ($i) { 
              if (!a[h[i]]++) print columns > h[i]".txt"; 
              print $1,$2,$3,$4,$5 > h[i]".txt" 
          } 
     }'  file
  • split($0,h)- 將第一條記錄拆分為數組h以獲得標題列名稱
  • columns=sprintf("%s %s %s %s %s",h[1],h[2],h[3],h[4],h[5])- 構造公共列字元串A B C D E
  • if($i)- 如果目前欄位(從第 6 個欄位開始)不為,即不是""(空字元串)或0- 準備好進行進一步處理
  • h[i]- 指向目前文件名,即F1等(或如您所寫:表示一些 id
  • if (!a[h[i]]++) print columns > h[i]".txt"- 如果名稱下的文件h[i]是第一次寫入 - 將標題/列行列印到它(作為第一行)

查看結果:

$ head F*.txt
==> F1.txt <==
A B C D E
a2 b2 c2 d2 e2
a3 b3 c3 d3 e3

==> F2.txt <==
A B C D E
a3 b3 c3 d3 e3

==> F3.txt <==
A B C D E
a1 b1 c1 d1 e1

==> F4.txt <==
A B C D E
a2 b2 c2 d2 e2

==> F5.txt <==
A B C D E
a1 b1 c1 d1 e1
a2 b2 c2 d2 e2
a3 b3 c3 d3 e3

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