Reputation: 5259
I am using awk to get compute some sums and I want to store them in a file.
here is my input file:
misses 15
hit 18
misses 20
hit 31
And I want to print the total misses, and total hits in a file.
If I run this:
awk 'BEGIN { hits=0; misses=0; } /^hit/{ hits+=$2}; /^misses/{misses+=$2}; END {print "Hits: " hits "\nMisses: " misses }' t.txt
I see them in the terminal.
Now I want to write the in a file:
I tried this:
#!/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
but $misses, and $hits
do not have value.
I also tried this:
#!/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
that I saw on the web, in order to see what $result will return me but I get this error:
./test2.sh: line 2: Hits:: command not found
Upvotes: 0
Views: 575
Reputation: 4137
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!
Upvotes: 1
Reputation: 40733
Here is a more compact solution:
#!/bin/bash
awk '
{tally[$1] += $2}
END {
for (outcome in tally) {
print outcome ":", tally[outcome]
}
}' t.xt > $1
You don't have to initialize variables in AWK. The first time you use it, AWK will assume 0 for number, or "" for string, depend on the context.
Upvotes: 0
Reputation: 531275
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 )
Upvotes: 3