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 会返回给我什么,但我收到了这个错误:

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

3 回答 3

3

hits and misses are only variables inside awk, not in the shell after awk exits. Just do the following:

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

In your second attempt, you cannot put a space after the '=':

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

simply redirect the output of the awk command:

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

the redirection operator > can be appended to any shell command to redirect its standard output to a file. changing it to >> appends the command's output to the file instead of completely overwriting the file, as you noticed.

edit:

the reason this didn't work:

#!/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

is because $misses and $hits are local variables to the awk script. thus the shell has no knowledge of them outside that statment, so when you try to echo them, you get blanks.

and this doesn't work:

#!/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

for multiple reasons.

1) when assigning variables in bash, you cannot have whitespace around the equal sign, so the second line must begin:

`result=$(echo...`

2) the echo statement inside your substitution (echo $output) is unnecessary. this is because a) $output is undefined so echo produces no output, and b) the second statement in the pipeline (the awk statement) completely ignores the standard output of the command preceding it in the pipeline anyway since you specified a filename for it to act on (t.txt). so the second line could just be:

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

3) the echo statement at the end will display the results all on one line, despite the fact that the awk statement prints two lines. this is because you did not quote the variable in your echo statement. try this instead:

echo "$result"

as a rule in bash scripting, you should ALWAYS quote the variables you are passing or printing, unless you know for sure why you don't want to.

hope that helps you learn a bit more about what you were trying!

于 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 回答