2017-02-22 137 views
-1

我有一個文件,我想選擇列$ 3相同的行。現在我已經對它們進行了分組,但是如果列$ 1(和/或$ 2)滿足特定條件,我想在這些行上執行某些操作。例如,如果$ 1和$ 2中的所有值(在$ 3中具有相同值的行中的所有值)相互在0.1以內,我想要取1到2列的平均值(爲此有同樣的3美元)。如果它更大,我想只打印那些線而不用平均。在這些行上選擇匹配的列和操作

我的輸入是這樣的:

1.3 22.5 ALFA 45 50 
1.4 22.6 ALFA 45 50 
1.5 22.7 ALFA 45 50 
1.6 22.8 ALFA 45 51 
5.5 8.5 BETA 53 15 
5.6 8.6 BETA 53 15 
5.5 8.5 BETA 53 15 
7.6 10.6 GAMA 75 13 
7.7 10.7 GAMA 76 13 
12 11.5 GAMA 75 13 
4.5 4.5 DELTA 65 12 
4.6 5.7 DELTA 65 12 
12.1 8 EPS 44 16 
12.2 8 EPS 44 16 

我希望我的輸出是:

out1.txt:

5.53 8.53 BETA 53 15 
12.15 8 EPS 44 16 

out2.txt:

1.3 22.5 ALFA 45 50 
1.4 22.6 ALFA 45 50 
1.5 22.7 ALFA 45 50 
1.6 22.8 ALFA 45 50 
7.6 10.6 GAMA 75 13 
7.7 10.7 GAMA 76 13 
12 11.5 GAMA 75 13 
4.5 5.6 DELTA 65 12 
4.6 9  DELTA 65 12 
+0

示例輸入/輸出將幫助您獲得更多響應並驗證腳本。這似乎是一個簡單的練習'awk' – karakfa

+0

我可能不清楚這個問題。我沒有一個腳本來驗證,我只是不知道如何編寫一個用於選擇一個行,當我不選擇特定的模式,但只有一定的匹配。 –

+0

人們可以驗證自己的腳本是否符合您的輸出。編寫一個好的規範是一個不小的練習。例如,如果您的$ 3值填充範圍「0.9 0.95 1 1.05 1.1 1.15 1.2」或集中在兩個值左右? (雙模)'0.9 1.1 0.95 2 2.01 1.91' – karakfa

回答

0

awk轉r escue!

awk '{k=$3; 
     if(!(k in min1)) {max1[k]=min1[k]=$1; max2[k]=min2[k]=$2} 
     sum1[k]+=$1; sum2[k]+=$2; count[k]++; 
     if(max1[k]<$1) max1[k]=$1; if(min1[k]>$1) min1[k]=$1; 
     if(max2[k]<$2) max2[k]=$2; if(min2[k]>$2) min2[k]=$2}  
    END {for(k in sum1) 
      if(max1[k]-min1[k]<=0.1 && max2[k]-min2[k]<=0.1) 
       printf "%.2f\t%.2f\t%s\n",sum1[k]/count[k],sum2[k]/count[k],k}' file 

12.15 8.00 EPS 
5.53 8.53 BETA 

很多代碼,但幾乎微不足道,雖然順序不被保留。

+0

謝謝!如果我的輸入文件中有更多列,我怎麼打印它們?就像編輯的問題輸入/輸出一樣。 使用'print {$ 4,$ 5}'這樣的東西爲每一行輸出相同的第4列和第5列的值,而不是相應的行 –

+0

,最簡單的方法就是使它們成爲密鑰的一部分。改爲'k = $ 3 FS $ 4 FS $ 5'。有一次你必須投票並接受答案。否則,人們會停止回答你的問題。 – karakfa

+0

好的。而min1和min2在這種情況下是awk函數的最小值和最大值或名稱的值? –