2016-07-05 16 views
3

我有一個表類似於以下一個(但更長的時間):awk中用於與共享的值的列選擇行

A  B  C   D   E 
1  YRI_1 YRI_2  10761  0 
2  YRI_3 YRI_3  7825  0 
3  YRI_1 YRI_4  9880  0 
4  YRI_1 Medit_1 79707  0 
5  YRI_2 Medit_2 73865  0 
6  YRI_2 Medit_3 77165  0 
7  YRI_3 Medit_4 76428  0 
8  YRI_3 CHB_1  8273  0 
9  YRI_2 CHB_2  10668  0 
10 YRI_1 CHB_3  8391  0 

我想獲得:

A  B  C   D   E 
2  YRI_3 YRI_3  7825  0 
4  YRI_1 Medit_1 79707  0 
5  YRI_2 Medit_2 73865  0 
9  YRI_2 CHB_2  10668  0 

即我會比如YRI_1/Medit_1都有一個「1」,因此它是一個想要的行,但我不想保留例如YRI_1/Medit_10,因爲這是「 10「,儘管它包含」1「。

我試着用AWK:

for i in {1..4} 
do 
    awk '$2=="*$i"||$3=="*$i" {print $1,$2,$3,$4,$5}' table > desired_table 
done 

其中$我本來是要在每次迭代由下一個編號列表中的1..4取代,而且我假裝*意味着什麼,因爲我我對這個數字感興趣(但我想這不是用awk來實現的)。

回答

3

您可以使用此命令awk

awk 'split($2, a, /_/) && split($3, b, /_/) && a[2] == b[2]' file 

A  B  C   D   E 
2  YRI_3 YRI_3  7825  0 
4  YRI_1 Medit_1 79707  0 
5  YRI_2 Medit_2 73865  0 
9  YRI_2 CHB_2  10668  0 
  • 我們用2個split功能拆分$2$3,然後比較分裂陣列平等的第二個領域。
  • split返回結果數組中元素的數量。通過使用awk 'split($2, a, /_/) && split($3, b, /_/) &&,我們確保split返回非零值。
+1

也許值得一提的是'split'(即數組中元素的數量)的返回值,你現在正在依靠'&&'來工作。 –

+1

是的,因爲我們要比較'a [2]'和'b [2]',我們需要'split'來返回非零值 – anubhava

+1

這就像一個魅力!非常感謝。我試圖理解語法,如果我先說第二列「a」和第三個「b」並聲明分隔符是「_」,然後你要求那些行的列「a」和「b」具有相同的第二個元素(即數字)? – Michael

1

從相關列中刪除除數字([^ 0-9])以外的所有字符,如果匹配則打印。

awk 'NR==1 || (gensub(/[^0-9]/,"","g",$2)==gensub(/[^0-9]/,"","g",$3))' file 
A  B  C   D   E 
2  YRI_3 YRI_3  7825  0 
4  YRI_1 Medit_1 79707  0 
5  YRI_2 Medit_2 73865  0 
9  YRI_2 CHB_2  10668  0