如何添加awk的每個輸出

如何添加awk的每個輸出

如何對 awk 的每一行輸出執行加法?

例如

cat foo | awk '{print $1}
42
42
42

我正在尋找 42+42+42 (126) 的答案。

我正在嘗試編寫一個 for 循環來執行此操作,但必須有一種更簡單的方法

#Not Working, and way too complex
cat foo |awk  '{ print $1 }'|for i in $1 do; foo=$(( foo+$(i) )) done| echo $foo

我可以透過管道連接wc -l,但只會列印行數,不會評估它們。

如何評估 awk 中的每一行?

答案1

使用您的範例的基本方法:

awk '{sum+=$1} END {print sum}' file

答案2

如果您可以控制 awk 程序,請在 awk 中進行添加,如 @jasonwryan 所示。

如果您確實想對 awk 輸出的數字求和,請將輸出透過管道傳輸到以下之一:

| { tr '\n' '+' ; echo 0; } | bc
| { while read line; do ((sum+=line)); done; echo $sum; }

在第二個範例中,echo 指令位於分組大括號內,因為 bash 在子 shell 中執行管道,因此當子 shell 退出時,對 $sum 變數的變更將不存在。

答案3

Bash 不能處理小數,但它可以處理整數的簡單操作,你只需要使用像這樣的技巧流程替代使變數在循環外可存取:

n=0;while read i; do let n+=$i; done < <(awk '{print $1}' foo); echo $n;

或者

n=0;while read i; do n=$((n+i)); done < <(awk '{print $1}' foo); echo $n;

那裡n=0只是為了確保$n始終為 0,否則,第二次運行這些命令將返回 252 而不是 126。


雖然最直接的方法是使用gawk來進行計算,但您也可以使用 Perl 單行程式碼:

awk '{print $1}' foo | perl -lne '$k+=$_;END{print "$k"};'

-l標誌刪除換行符 ( chomp) 並在每個列印字串的末尾添加 1,這-n意味著逐行讀取文件,將每一行儲存為$_並執行 提供的腳本-e

或用 Perl 完成整件事情:

perl -alne '$k+=$F[0];END{print "$k"};' foo

Perl 的標誌-a開啟自動行分割(如gawk)。預設情況下,欄位按空格分割,但可以使用 進行更改-F。結果欄位保存為@F數組,因此第一個欄位是$F[0]

答案4

我通常用於像這樣的簡單總計的單行方法是通過管道傳輸到 xargs 以在一行上獲取 awk 的所有輸出,然後通過 sed 將空格轉換為加號,最後轉換為 bc 進行計算:

cat foo | awk '{print $1} | xargs | sed -e 's/ /+/g' | bc

相關內容