awk
を使用して列の特定の数値を合計しようとしています。 「smiths」の列3だけを合計して合計で212にしたいと思います。「smiths」だけでなく、awk
を使用して列全体を合計できます。私が持っています:
awk 'BEGIN {FS = "|"} ; {sum+=$3} END {print sum}' filename.txt
また、PuTTYを使用しています。助けてくれてありがとう.
smiths|Login|2
olivert|Login|10
denniss|Payroll|100
smiths|Time|200
smiths|Logout|10
awk -F '|' '$1 ~ /smiths/ {sum += $3} END {print sum}' inputfilename
-F
フラグはフィールド区切り文字を設定します。シェルの特殊文字なので、一重引用符で囲みます。$1 ~ /smiths/
は、次の{code block}を、最初のフィールドが正規表現/smiths/
と一致する行にのみ適用します。ここでは実際には正規表現を使用していないため、特定の値のみを使用しているため、次のように簡単に使用できます。
awk -F '|' '$1 == "smiths" {sum += $3} END {print sum}' inputfilename
文字列の等価性をチェックします。これは、別の回答で述べたように、正規表現/^smiths$/
を使用することと同等です。これには、^
アンカーを使用して文字列の先頭(フィールド1の先頭)のみを照合し、$
アンカーを使用して文字列の末尾のみを照合します。正規表現にどの程度慣れているかわからない。それらは非常に強力ですが、この場合、文字列の等価性チェックを簡単に使用できます。
別のアプローチは、awk連想配列を使用することです。詳細は here です。この行は、必要な出力を生成します。
awk -F '|' '{a[$1] += $3} END{print a["smiths"]}' filename.txt
副作用として、配列には他のすべての値が格納されます。
awk -F '|' '{a[$1] += $3} END{for (i in a) print i, a[i]}' filename.txt
出力:
smiths 212
denniss 100
olivert 10
今のところとても良いです。必要なのは、ブロックの前にセレクターを追加して、合計を追加することだけです。ここで、最初の引数に「smiths」のみが含まれていることを確認します。
awk 'BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}'
オプションとしてフィールドセパレータを指定することで、これを少し短くすることができます。 awk
では、コマンドラインで変数を初期化することをお勧めします。
awk -F'|' '$1 ~ /^smiths$/ {sum+=$3} END {print sum}'
私は個人的にはawk
セクションをできるだけ単純にして、それなしでできる限りのことをしたいと思っています。 ComingledロジックはUnixパイプラインの能力を活用していないため、密接に関連するユースケースの理解、デバッグ、変更が困難です。
cat filename.txt | Perl -pe 's{.*|}{}g' | awk '{sum+=$1} END {print sum}'
cat filename.txt | grep smiths | awk -F '|' '{sum+=$NF} END {print sum}'
-F
オプションでセパレータを指定します。$NF
は「最後の列」用です。