如何對 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