2013-03-15 38 views
1

我試圖寫一個bash腳本,有幾個數據列讀取文件,並在乘以通過第三列的每個值的第二列中的每個值,將所有的乘法結果一起。對變量用awk與運營

例如,如果該文件是這樣的:

Column 1 Column 2 Column 3 Column 4 
genome  1   30   500 
genome  2   27   500 
genome  3   83   500 
... 

該腳本應乘以1 * 30以得到30,然後2 * 27,得到54(並添加到30),然後3 * 83給249(並添加到84)等。

我一直在試圖用awk來解析輸入文件,但我不能確定如何讓操作由線進行線路。現在它在讀取第一行並且執行變量操作後停止。

這是我到目前爲止已經寫的:

for file in fileone filetwo 
do 
    set -- $(awk '/genome/ {print $2,$3}' $file.hist) 
    var1=$1 
    var2=$2 
    var3=$((var1*var2)) 
    total=$((total+var3)) 

    echo var1 \= $var1 
    echo var2 \= $var2 
    echo var3 \= $var3 
    echo total \= $total 
done 

我試圖把一個「而改爲」周圍的一切循環,但無法得到的變量與各行進行更新。我想我正在以這種錯誤的方式去做!

我很新的Linux和Bash腳本所以任何幫助將不勝感激!

回答

2

這是因爲AWK讀取整個文件並運行其程序上的每一行。所以,如果你awk '/genome/ {print $2,$3}' $file.hist得到的輸出將看起來像

1 30 
2 27 
3 83 

等,這意味着在bash腳本中,set命令做出以下變量賦值:

$1 = 1 
$2 = 30 
$3 = 2 
$4 = 27 
$5 = 3 
$6 = 83 

等,但你只使用$1$2,這意味着文件的其餘內容 - 第一行之後的所有內容 - 都將被丟棄。

老實說,除非你正在做只是爲了學習如何使用bash,我會說只是做它在AWK。由於awk會自動遍歷文件中的每一行,因此可以很容易地將第2列和第3列相乘並保持運行總數。

awk '{ total += $2 * $3 } ENDFILE { print total; total = 0 }' fileone filetwo 

ENDFILE這裏是一個特殊的地址,這意味着「在每個文件的結尾運行此下一個塊,而不是在每行」。

如果你做這個教育目的,讓我這樣說:你需要知道在bash做算術的唯一的事情是,你應該永遠不會做算術在bash :-P認真不過,當你想操縱數字,bash是該作業中適合使用的工具之一。但是,如果你真的想知道,我可以編輯它以包含一些關於如何主要在bash中執行此任務的信息。

+0

感謝您的解釋!這實際上是一個更大的bash腳本的一小部分,所以我試圖把所有的東西都放在一起,只是爲了簡單。 – Joltex 2013-03-15 22:00:37

0

我同意awk是一般更適合這樣的工作,但如果你是好奇什麼是純bash實施會是什麼樣子:

for f in file1 file2; do 
    total=0 
    while read -r _ x y _; do 
     ((total += x * y)) 
    done < "$f" 
    echo "$total" 
done 
+0

酷!謝謝。 – Joltex 2013-03-15 22:01:12