2012-04-28 46 views
1

我有一個這樣的文本文件。如何使用bash從文本文件中提取列

res   ABS sum  
SER A 1 161.15 138.3 
CYS A 2 66.65 49.6 
PRO A 3 21.48 15.8 
ALA A 4 77.68 72.0 
ILE A 5 15.70 9.0 
HIS A 6 10.88 5.9 

我想提取第一列的基礎上最後一列(總和)的值(RES)的名稱。如果sum> 25並且總和爲<,那麼我必須打印resnames。25.如何獲得像這樣的輸出?

+0

根據評論中的對話,你能澄清你實際上想要打印的resnames嗎?沒有一個數字既不能少於25也不能超過25個。如果'sum!= 25',你想要打印的是重新命名嗎?或者如果例如總和爲< 25 OR ABS > 25',你想打印嗎? – 2012-04-28 15:28:58

回答

1

這應做到:

awk 'BEGIN{FS=OFS=" "}{if($5 != 25) print $1}' bla.txt 
1

雖然可以在bashwhile read循環做到這一點,它更容易,並且最有可能更快,使用awk

awk '$5 != 25 { print $1 }' 

請注意,你的邏輯print resnames if sum >25 and sum<25相同print if sum != 25

+1

總和> 25 *和* sum <25什麼都不留。或者會。 – Kevin 2012-04-28 13:56:03

+1

@凱文除了25本身。 – 2012-04-28 13:57:32

+0

@TimPote:那麼25與此同時> 25和<25? – 2012-04-28 14:15:35

1

考慮使用awk。它是處理文本列的簡單工具(以及更多)。這裏有一個簡單的awk tutorial,它會給你一個概述。如果你想在bash腳本中使用它,那麼this教程應該有所幫助。

運行此命令行上給你的,你怎麼能做到這一點的想法:

> echo "SER A 1 161.15 138.3" | awk '{ if($5 > 25) print $1}' 
> SER 
> echo "SER A 1 161.15 138.3" | awk '{ if($5 > 140) print $1}' 
> 
+0

@Demanie謝謝。 – Joel 2012-05-03 12:24:02

0
while read line 
do 
v=($line) 
sum=${v[4]} 
((${sum/.*/} >= 25)) && echo ${v[0]} 
done < file 

您需要跳過第一道防線。

由於慶典不處理浮點值,這將打印25是不完全大於25

這可以通過調用公元前算術處理。

tail -n +2 ser.dat | while read line 
do 
    v=($line) 
    sum=${v[4]} 
    gt=$(echo "$sum > 25" | bc) && echo ${v[0]} 
done 
0

那麼好的舊切呢? :)

說你想有第二列,

cat your_file.txt | sed 's, +, ,g' | cut -d" " -f 2 

什麼是這個命令而sed的? cut期望列由字符或固定長度的字符串分隔(請參閱文檔)。

+0

只是爲了讓你知道,這個解決方案有幾個問題。首先,這是一個[貓無用的使用方法]的一個最好的例子(http://partmaps.org/era/unix/award.html)。 sed可以在不需要管道的情況下處理文件。其次,awk沒有切割的字段分隔的限制,所以你可以做同樣的一個'$打印在2' AWK無需sed的。第三,它沒有做OP的要求。他們想*有條件地*打印第二個字段。你的*總是*打印第二個字段。 – 2012-05-05 15:23:20

相關問題