簡體   English   中英

在變量上使用awk

[英]Using awk with Operations on Variables

我正在嘗試編寫一個Bash腳本,該腳本讀取具有幾列數據的文件,並將第二列中的每個值乘以第三列中的每個值,並將所有這些乘法的結果相加。

例如,如果文件如下所示:

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腳本的新手,所以將不勝感激!

這是因為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中執行此任務的信息。

我同意awk通常更適合這種工作,但是如果您好奇純bash實現會是什么樣子:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM