awk
。 「スミス」の列3だけを合計して、合計212を取得したいと思います。「スミス」だけでなく、awk
を使用して列全体を合計できます。持っているもの:
awk "BEGIN {FS = "|"} ; {sum+=$3} END {print sum}" filename.txt
パテも使用しています。ご協力いただきありがとうございます。
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/
は、最初のフィールドが正規表現/smiths/
と一致する行にのみ次の{コードブロック}を適用します。 - 残りはコードと同じです。
ここでは実際には正規表現を使用していないため、特定の値だけを使用するので、同じように簡単に使用できます。使用:
awk -F "|" "$1 == "smiths" {sum += $3} END {print sum}" inputfilename
文字列の同等性をチェックします。これは、別の説明で説明されているように、正規表現/^smiths$/
を使用するのと同じです。回答。文字列の先頭(フィールド1の先頭)のみに一致する^
アンカーと、のみに一致する$
アンカーが含まれます。文字列の末尾に一致します。正規表現にどれだけ慣れているかわかりません。正規表現は非常に強力ですが、この場合、文字列の等価性チェックを同じように簡単に使用できます。
コメント
- ちなみに、私のお気に入りのawkリファレンスは grymoire.com/Unix/Awk.html です。非常に役立つページ。
- @Wildcardに感謝します!あなたのアドバイスに基づいて、特定のファイルの非圧縮サイズを大きなzipアーカイブにきちんと集約することができました:)
回答
別のアプローチは、awk連想配列を使用することです。詳細ここ。この行は、目的の出力を生成します。
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
セクションをできるだけシンプルに保ち、それなしでできる限りのことをしたいと思います。 。混合ロジックは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
は「最後の列」用です。
コメント
-
cat
とgrep
はここでは不要です。 - なぜgrepは@Andreyが不要なのですか? OPは、" smiths "行のみを追加したいと考えています。 ' awkステートメントを変更する必要がありますか?
- @ELはい、awkステートメントを
/smiths/{...}
grep呼び出しがない場合。これは簡単な変更ですが、実行中のプロセスの数を減らし、エラー制御を簡素化し、コードをより明確にするという大きな利点があります。