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プログラムを制御できる場合は、@jasonwryanが提案したようにawkに追加してください。
awkが出力した数値を実際に合計するには、出力を次のいずれかにパイプします。
| { tr '\n' '+' ; echo 0; } | bc
| { while read line; do ((sum+=line)); done; echo $sum; }
2番目の例では、echoコマンドはグループ化中括弧内にあります。 bashはサブシェルでパイプを実行するため、$ 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
。それ以外の場合、このコマンドを2回目に実行すると、126ではなく252が返されます。
最も簡単な方法はgawk
計算を実行することですが、Perlシングルライナーを使用することもできます。
awk '{print $1}' foo | perl -lne '$k+=$_;END{print "$k"};'
この-l
フラグは改行文字(chomp
)を削除し、印刷された各文字列の末尾に1を追加します。これは-n
、ファイルを1行ずつ読み、各行をとして保存し、提供された$_
スクリプトを実行することを意味します-e
。
あるいは、Perlはすべてのことをします。
perl -alne '$k+=$F[0];END{print "$k"};' foo
-a
自動行分割をオンにするPerlフラグ(たとえば、デフォルトではフィールドはスペースで区切らgawk
れますが、を使用して変更できます。-F
結果フィールドは@F
配列として保存されるため、最初のフィールドはです$F[0]
。
答え4
このような単純な合計に一般的に使用される1行のアプローチは、xargsにパイプしてawkのすべての出力を1行にインポートし、sedを使用してスペースをプラス記号に変換し、最後に計算のためにbcに変換することです。
cat foo | awk '{print $1} | xargs | sed -e 's/ /+/g' | bc