0

いくつかの合計を計算するためにawkを使用していて、それらをファイルに保存したいと思います。

これが私の入力ファイルです:

misses 15
hit 18
misses 20
hit 31

そして、ミスの合計とヒットの合計をファイルに出力したいと思います。

これを実行すると:

awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt 

ターミナルで見かけます。

今、私はファイルに書きたいです:

私はこれを試しました:

#!/bin/bash
 awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt

echo misses $misses > $1; #first one overwrites the previous $1 is the argument given in the command line
echo hits $hits>> $1; # all the othes append to the .txt file

しかし、$misses, and $hits価値はありません。

私もこれを試しました:

#!/bin/bash
result= $(echo $output | awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt )
# $NF if I want the last column
echo $result

$ resultが何を返すかを確認するために、Webで見たものですが、次のエラーが発生します。

./test2.sh: line 2: Hits:: command not found
4

3 に答える 3

3

hitsmissesは内部の変数であり、終了awk後のシェルではありませんawk。次の手順を実行してください。

#!/bin/bash
awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt > $1

2回目の試行では、「=」の後にスペースを入れることはできません。

result=$(echo $output | awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt )
于 2013-01-23T15:24:15.550 に答える
1

awkコマンドの出力をリダイレクトするだけです。

awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt >file.txt

リダイレクト演算子>を任意のシェルコマンドに追加して、標準出力をファイルにリダイレクトできます。>>お気づきのように、ファイルを完全に上書きするのではなく、コマンドの出力をファイルに追加するように変更します。

編集:

これが機能しなかった理由:

#!/bin/bash
 awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt

echo misses $misses > $1; #first one overwrites the previous $1 is the argument given in the command line
echo hits $hits>> $1; # all the othes append to the .txt file

$missesと$hitsはawkスクリプトのローカル変数だからです。したがって、シェルはそのステートメントの外でそれらの知識を持っていないので、それらをエコーし​​ようとすると、空白になります。

これは機能しません:

#!/bin/bash
result= $(echo $output | awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt )
# $NF if I want the last column
echo $result

複数の理由で。

1)bashで変数を割り当てる場合、等号の前後に空白を含めることはできないため、2行目を開始する必要があります。

`result=$(echo...`

2)置換()内のechoステートメントecho $outputは不要です。これは、a)$outputが定義されechoていないため出力が生成されず、b)パイプラインの2番目のステートメント(awkステートメント)が、作用するファイル名を指定したため、パイプラインでその前にあるコマンドの標準出力を完全に無視するためです。 (t.txt)。したがって、2行目は次のようになります。

result=$(awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt)

3)最後のechoステートメントは、awkステートメントが2行を出力するにもかかわらず、結果をすべて1行に表示します。これは、echoステートメントで変数を引用しなかったためです。代わりにこれを試してください:

echo "$result"

原則として、bashスクリプトでは、渡したり印刷したりする変数を常に引用する必要があります。ただし、必要がない理由が確実にわかっている場合を除きます。

それがあなたが何をしようとしていたかについてもう少し学ぶのに役立つことを願っています!

于 2013-01-23T15:24:08.617 に答える
0

よりコンパクトなソリューションは次のとおりです。

#!/bin/bash
awk '
    {tally[$1] += $2}
    END {
        for (outcome in tally) {
            print outcome ":", tally[outcome]
        }
    }' t.xt > $1

AWKで変数を初期化する必要はありません。初めて使用するとき、AWKは、コンテキストに応じて、数値を0、文字列を「」と見なします。

于 2013-01-23T15:32:29.303 に答える