以下を計算するforループを実行したいと思います。awk
10回実行して出力を合計して最終結果を印刷します。コードは以下に添付されています:
sum=0
for i in {1..10}
do
count=`awk '{if ($NF==$i) {print $NF}}' * | wc -l`
sum=$[sum+count]
echo $sum
done
問題は、に変更すると$NF==$i
結果$NF==1
は正確ですが、forループを使用して10回実行したいということです。
コードには何の問題がありますか?
答え1
以下では、すべての作業を実行する方が効率的ですawk
。
awk -v n=0 '
{for (i = 1; i <= 10; i++) if ($NF == i) {n++; break}}
END {print n}' ./*
または最後のフィールドが常に整数の場合:
awk -v n=0 '
$NF >= 1 && $NF <= 10 {n++}
END {print n}' ./*
または、語彙比較をしたい場合、これらの数字の表現(1
、、...の代わりに)のみ2
を許可したい場合:3
10
01
1e0
1.0
awk -v n=0 '
$NF ~ /^([123456789]|10)$/ {n++}
END {print n}' ./*
答え2
ここでの問題は、単一引用符内でシェル変数拡張を実行しようとしていることです' ... '
。しかし、一重引用符の中ではシェル変数拡張が一時停止されました(例:この回答ここかLhunathとGreyCatのBashガイド)、これが実際に推奨される理由です。$
個々の入力フィールドを逆参照するときに同様の機能が実行されるためawk
(ただし、フィールド番号は、例えば、のように変数名で表されることもあります$NF
)、単一の入力フィールドにプログラムをカプセル化します。同時「変数拡張」。
awk
あなたの場合は、以下を使用してプログラムに値を「インポートする」ことができます。
awk -v fieldnr="$i" '{if ($NF==fieldnr) {print $NF}}'
それにもかかわらず、あなたの問題は完全に解決可能であるように見えるawk
ので、達成しようとしているタスクをより詳細に説明し、よりエレガントでより速いアプローチを見つけようとします。質問が正しいかもしれません...
答え3
あなたのスクリプトが私が思うように実行する場合(つまり、sum
1から10まで繰り返しながら一致する行の増分値を印刷する場合)、シェルスクリプトが生成する出力を生成するために実際に必要なものは次のとおりです。
awk '
{ counts[$NF]++ }
END {
for (i=1; i<=10; i++) {
sum += counts[i]
print sum
}
}
' *
上記はテストするサンプル入力/出力を提供していないため、テストされていません。
答え4
#!/bin/bash
# Tested with -- GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
set -e
for i in `seq 1 1000`
do
echo $i
# Run your command here
done