Bob
Bob

Reputation: 1001

bash scripting, how to parse string separated with :

I have lines that look like these

value: "15"

value: "20"

value: "3"

I am getting this as input pipe after grepping

... | grep value:

What I need is a simple bash script that takes this pipe and produce me the sum 15 + 20 + 3

So my command will be:

... | grep value: | calculate_sum_value > /tmp/sum.txt

sum.txt should contain a single number which is the sum.

How can I do with bash? I have no experience with bash at all.

Upvotes: 1

Views: 195

Answers (2)

glenn jackman
glenn jackman

Reputation: 246764

My first try was to grab the stuff on the right of the colon and let bash sum it:

$ sum=0
$ cat sample.txt | while IFS=: read key value; do ((sum += value)); done
bash: ((: "15": syntax error: operand expected (error token is ""15"")
bash: ((: "20": syntax error: operand expected (error token is ""20"")
bash: ((: "3": syntax error: operand expected (error token is ""3"")
0

So, have to remove the quotes. Fine, use a fancy Perl regex to extract the first set of digits to the right of the colon:

$ cat sample.txt | grep -oP ':\D+\K\d+'
15
20
3

OK, onwards:

$ cat sample.txt | grep -oP ':\D+\K\d+' | while read n; do ((sum+=n)); done; echo $sum
0

Huh? Oh yeah, running while in a pipeline puts the modifications to sum in a subshell, not in the current shell. Well, do the echo in the subshell too:

$ cat sample.txt | grep -oP ':\D+\K\d+' | { while read n; do ((sum+=n)); done; echo $sum; }
38

That's better, but still the value is not in the current shell. Let's try something trickier

$ set -- $(cat sample.txt | grep -oP ':\D+\K\d+')
$ sum=$(IFS=+; bc <<< "$*")
$ echo $sum
38

And yes, UUOC, but it's a placeholder for whatever the OP's pipeline was.

Upvotes: 3

user000001
user000001

Reputation: 33317

You could try awk. Something like this should work

... | grep value: | awk '{sum+=$2}END{print sum}'

And you could possibly avoid grep alltogether like this

.... | awk '/^value:/{sum+=$2}END{print sum}'

Update:

You can add the " character as a field seperator with the -F option.

... | awk -F\" '/^value:/{sum+=$2}END{print sum}'

Upvotes: 4

Related Questions