2016-10-03 15 views
-1

我有一個文本文件,包含許多行和列,我想通過'列名'來grep列。linux grep模式列數未知數

M121 M125 M123 M124 M131 M126 M211 N 
0.41463252 1.00296561 -0.1713496 0.15923644 -1.49682602 -1.9478695 1.45223392 … 
-0.46775802 0.14591103 1.122446 0.83648981 -0.3038532 -1.1841548 2.18074729 … 
0.67736835 2.12969375 -0.8187298 0.13582824 -1.49290987 -0.6798428 1.04353114 … 
0.08673344 -0.40437672 1.8441559 -0.63679375 0.47998832 0.1702844 0.54029264 … 
-0.32606297 -0.95551833 0.6157599 0.02819133 1.44818627 -0.9528659 0.09207864 … 
-0.51781121 0.88806507 -0.2913757 -0.00463802 0.05037374 0.953773 0.01244763 … 
-0.25724472 0.05119051 0.2109025 -0.26083822 -0.52094072 -0.938595 -0.01275275 … 
1.94348766 -1.83607523 1.2010512 -0.54109756 -0.88323831 -0.6263788 -0.96973544 … 
0.1900408 -0.61025656 0.4586306 -0.69181051 -0.90713834 0.3589271 0.6870383 … 
0.54866057 -0.03861159 -1.505861 0.54871682 -0.24602601 -0.3941754 0.85673905 … 

例如,我想grep M211列但我不知道列的數量。我想:

awk '$i == "M211"' filename or awk '$0 == "M211"' filename 

AWK:非法場$(),名稱爲 「我」 輸入記錄編號1,文件名 源1號線

有沒有什麼解決辦法嗎?謝謝。

+0

爲什麼你的例子就是選擇一個列名,M211,以「grep的」,它不是在你的樣品輸入存在嗎? –

+0

@EdMorton我有很多列,其中之一是M211,如果我選擇M121或M125,恐怕我得到的答案是awk'$ 1 ==「M121」'文件名或awk'$ 2 ==「M125 「'文件名不是我想要的答案。我想得到的答案是我不知道列的數量,但可以通過'列名'選擇列。謝謝。 –

+0

如何選擇不存在的示例幫助那個列名?您錯過了在這裏提出問題所需的預期輸出(請參閱[問]],因爲您發佈的樣本輸入和命令行的預期輸出是什麼都不是。給我們一個命令來測試這個產生沒有輸出,因爲你提供的測試輸入是沒有意義的 - 選擇一個存在的值,這樣你可以在你的問題中顯示有意義的期望輸出,並且我們有一些具體的測試對象。現在我們只是猜測你想要的輸出是什麼。 –

回答

2

另在AWK:

$ awk 'NR==1 {for(i=NF;i>0;i--) if($i=="M125") break; if(!i) exit} {print $i}' file 
M125 
1.00296561 
0.14591103 
2.12969375 
-0.40437672 
-0.95551833 
0.88806507 
0.05119051 
-1.83607523 
-0.61025656 
-0.03861159 

解釋:

NR==1 {      # for the first record 
    for(i=NF;i>0;i--)   # iterate fields backwards for change 
     if($i=="M125") break # until desired column, remember i 
     if (!i) exit   # if column not found, exit 
} 
{print $i}     # print value from ith field 
+0

簡單修復缺陷:'awk'NR == 1 {for(i = 1; i <= NF; i ++){if($ i ==「M125」)break} if(i> NF)exit} {print $ i} 'file' – Sundeep

+1

@Sundeep我正在嘗試保存字節...如何向後迭代器更短'if()'? :D –

+1

有很好的高爾夫球場:P應該是'i> 0'儘管 – Sundeep

3

awk解決方案 - 迭代輸入文件的第一行的列名稱,並保存列號,如果它匹配所需的模式。然後打印該列。無輸出,如果沒有找到匹配

$ awk 'NR==1{ for(i=1;i<=NF;i++){if($i=="M125")c=i;} if(c==0)exit; } 
     {print $c}' ip.txt 
M125 
1.00296561 
0.14591103 
2.12969375 
-0.40437672 
-0.95551833 
0.88806507 
0.05119051 
-1.83607523 
-0.61025656 
-0.03861159 


類似的解決方案與perl

$ perl -lane '@i = grep {$F[$_] eq "M123"} 0..$#F if $.==1; exit if [email protected]; 
       print @F[@i]' ip.txt 
M123 
-0.1713496 
1.122446 
-0.8187298 
1.8441559 
0.6157599 
-0.2913757 
0.2109025 
1.2010512 
0.4586306 
-1.505861 
  • @i = grep {$F[$_] eq "M123"} 0..$#F if $.==1爲標題行,得到指數的列值相匹配的字符串M123
  • exit if [email protected]退出如果找不到匹配
  • print @F[@i]打印匹配列
  • 假設就會有隻有一個匹配

的多個匹配,使用

perl -lane '@i = grep {$F[$_] =~ /^(M121|M126)$/} 0..$#F if $.==1; exit if [email protected]; 
      print join " ", @F[@i]' ip.txt 
+0

謝謝,那麼perl或python更容易進行上述操作? –

+0

對這個問題沒什麼區別 - awk足夠好,並且可以與大多數unix一起使用,但是如果你有其他文本操作和自動化,python/perl可能會更好 – Sundeep

+0

不,awk可用所有的UNIX安裝和你用python或perl進行其他文本操作的效果都不是很好 - 如果你正在做的不是文本操作以外的東西。 –

1

如果你更熟悉Python:

import csv 
column_name = "M125" 
with open("file", "rb") as f: 
    data_dict = csv.DictReader(f, delimiter=" ") 
    print column_name 
    for item in data_dict: 
    print item[column_name] 
1

(單位AWK「域」)的列做什麼用的名字,而不是數量,你應該首先創建的字段名稱映射到數字從此數組使用該陣列由字段名(一個或多個)索引,而不是場數(S)直接訪問他們剛剛進入字段:

$ awk 'NR==1{for (i=1;i<=NF;i++) f[$i]=i} {print $(f["M124"])}' file 
M124 
0.15923644 
0.83648981 
0.13582824 
-0.63679375 
0.02819133 
-0.00463802 
-0.26083822 
-0.54109756 
-0.69181051 
0.54871682 

,或者如果你不想硬編碼列名:

$ awk -v c=M124 'NR==1{for (i=1;i<=NF;i++) f[$i]=i} {print $(f[c])}' file 
M124 
0.15923644 
0.83648981 
0.13582824 
-0.63679375 
0.02819133 
-0.00463802 
-0.26083822 
-0.54109756 
-0.69181051 
0.54871682 

,並打印你選擇任意數量的順序列:

$ awk -v cols='M129 M124' 'NR==1{for (i=1;i<=NF;i++) f[$i]=i; n=split(cols,c)} {for (i=1;i<=n;i++) printf "%s%s", $(f[c[i]]), (i<n ? OFS : ORS)}' file 
M129 M124 
1.45223392 0.15923644 
2.18074729 0.83648981 
1.04353114 0.13582824 
0.54029264 -0.63679375 
0.09207864 0.02819133 
0.01244763 -0.00463802 
-0.01275275 -0.26083822 
-0.96973544 -0.54109756 
0.6870383 -0.69181051 
0.85673905 0.54871682