sponce
sponce

Reputation: 1399

How to evaluate in bash a sum of numbers

I have a naive bash question.

export A=`wc file.txt` 
export B=`echo $A[1] - 1 | bc`

The problem is that I cannot evaluate the first element in $A. I could do it with awk

echo $A | awk '{print $1}'

But it does not work if I insert it in the previous equation.

Maybe someone has an idea?

Upvotes: 0

Views: 101

Answers (3)

ghoti
ghoti

Reputation: 46826

I always like using read to read input if I can.

$ read a _ < <(wc -l /path/to/file)
$ b=$((a - 1))

In this case $_ is a throw-away variable containing the filename. Input redirection as others have suggested is also a perfectly viable option.

Note that you only need to export variables if you intend to use them in the environments called from within your shell.

Upvotes: 0

fedorqui
fedorqui

Reputation: 289495

You are setting the variable $A to the output of wc. Since you show $A[1] it looks like you want the 2nd value, that is, the number of words, but then you use $1 in awk, so I think you want number of lines, -l parameter in wc.

So from now on I am supposing you want to use lines. If not, just change the solution with -l instead of -w.

The thing is that wc file outputs many parameters. If you specify -w or -l, it gets its value together with the file name. But if you do indirection like wc -l < file.txt, you just get the number of lines, so you don't have to clean the output.

This way, you can do:

a=$(wc -l < file.txt)
b=$(echo "$a" -1 | bc)

All together, you may want to use this directly, without the need to store the intermediate value:

b=$(echo "$(wc -l <file.txt)" -1 | bc)

Or if you want to use awk, you can say:

awk -v lines="$(wc -l < file.txt)" 'BEGIN {print lines-1}'

Or even use $(( )) to perform calculations, as suggested by JID:

b=$(($(wc -l <file.txt) - 1 ))

or

((b=$(wc -l <file.txt)-1))

Upvotes: 4

linraen_das
linraen_das

Reputation: 16

Say, this one can be good:

   export A=$(wc < file.txt)
   export B=$(echo "$(echo $A | cut -d' ' -f1) - 1" | bc)

or even

export B=$(echo "$(wc < file.txt | cut -d' ' -f1) - 1" | bc)

if you are not going to use 'wc' result further.

The 'wc' command prints newline, word and byte counter (see man page), which are space-separated, so cut is good enough here.

If you need 'wc' result as an array, you need to split it and to write into a pre-declared 'A' array manually.

Upvotes: 0

Related Questions