2

I have a text file title 'results' and it contains

[  PASSED  ] 11 tests.
[  PASSED  ] 590 tests.
[  PASSED  ] 1231 tests.
[  FAILED  ] 4 tests.
[  FAILED  ] 500 tests.

I would like to add the PASSED tests and store into a variable. Add the FAILED tests, add them and store into another variable.

How can I do this?

3
  • 1
    You'll want to look into awk. Commented May 1, 2013 at 16:42
  • With a case statement. Commented May 1, 2013 at 16:43
  • 1
    Your title says bash:. Why do you want to do this in bash? It seems easier to write a small awk script, and run store the awk script's output in a bash variable. Commented May 1, 2013 at 16:44

4 Answers 4

3

One quick way using awk.

Assuming your test output is in a file called test.out:

#!/bin/bash
npasses=$(<test.out awk '
/ PASSED / { total += $4 }
END { print total }')

echo number of passing tests: $npasses

<test.out means awk reads from test.out.

/ PASSED / { total += $4 } appends the forth field to a variable called total, but only for lines matching the regex PASSED.

END { print total } runs at end of file, and prints the value stored in total.

Sign up to request clarification or add additional context in comments.

Comments

1

If the log is in a file, you can use

regex='\[ (PASSED|FAILED) \] (\d+) tests.'
while read -r line; do
    [[ $line =~ $regex ]] || continue
    count=${BASH_REMATCH[2]}
    case ${BASH_REMATCH[1]} in
        PASSED) let passed += count ;;
        FAILED) let failed += count ;;
    esac
done < input.txt

To read directly from another process, replace the last line with

done < <( sourcecommand )

Don't pipe the output of sourcecommand in to the while loop; that will cause passed and failed to be updated in a subshell.

Comments

1

Using bash 4's associative arrays:

declare -A total
while read _ result _ n _; do
    ((total[$result]+=$n))
done < results
for key in "${!total[@]}"; do
    printf "%s\t%d\n" "$key" ${total[$key]}
done
PASSED  1832
FAILED  504

Comments

0

Expanding from Mikel's answer, You can use eval to set the variables directly.

eval $(awk '/PASSED/ {pass += $4} /FAILED/ {fail += $4} END {print "pass="pass";fail="fail}' FILE_WITH_DATA)

You now have the variables set for you.

echo $pass
echo $fail

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.