4

I have a fileA that contains:

  0012,001650,0089

I want to get the sum of column 1 and column 2 and the quotient of column 3 and 60. Using awk I tried this

  col1=`awk -F, '{print $1}' $fileA | sed 's/0*//'`
  col2=`awk -F, '{print $2}' $fileA | sed 's/0*//'`
  col3=`awk -F, '{print $3}' $fileA | sed 's/0*//'`

  sum=$((col1 + col2))
  qou=$((col3 / 60))

But I got this error:

apn_processing.sh[226]: col1 + col2: The specified number is not valid for this command.

Can you give me another solution for this?

1
  • Do not use old and deprecated back-tics, use parentheses like this: col1=$(awk -F, '{print $1}' $fileA | sed 's/0*//') Commented Mar 3, 2015 at 7:06

4 Answers 4

3

shell is for sequencing calls to tools, that's all. If you're just doing text processing then do the whole job in awk:

$ awk -F, '{
  sum = $1 + $2
  quo = $3 / 60
  print sum, quo
}' "$fileA"
1662 1.48333
Sign up to request clarification or add additional context in comments.

2 Comments

how about if i only need whole number (rounded off) for the output?
@newbie: Then you can use awk's printf function with the appropriate format; printf "%d %d\n", sum, quo will truncate the fractional part.
3

You don't need to call awk 3 times to extract the fields:

$ IFS=, read -r a b c < file
$ echo $a
0012
$ echo $b
001650
$ echo $c
0089
$ echo $((10#$a + 10#$b))
1662
$ echo $((10#$c / 60))
1
$ bc  <<< "scale=3; $c/60"
1.483

In bash math, you can specific a number's base with the notation base#number, so you don't get tripped up by invalid octal numbers like "0089"

Comments

1

Especially since you're dealing with floating point arithmetic, I would recommend performing the calculations in awk:

sum=$(awk -F, '{print $1+$2}' file)
qou=$(awk -F, '{print $3/60}' file)

Comments

1

Assuming that you have reason to want to get the answers into shell variables:

$ read sum quo < <(awk -F, '{print ($1+$2), $3/60}' "$fileA")
$ echo $sum $quo
1662 1.48333

Unlike bash, awk has no problem with leading zeros on numbers that it receives as input. For example, observe that the following works just fine:

$ echo 016 08 | awk '{print $1, $2, $1+$2, $1/$2}'
016 08 24 2

Aside

mklement0 points out in the comments that GNU awk will try to interpret numbers beginning with zero as octal, falling back to decimal, if they are program constants as opposed to input. Consider:

$ awk 'BEGIN{a=016;b=08; print a, b, a+b, a/b}'
14 8 22 1.75

In the above, 016 is treated as octal. By contrast, 08, which is not a legal octal number, is treated as decimal.

2 Comments

Nicely done; as an aside: GNU awk somewhat ambiguously does recognize octals as literals inside a script (not through input), and falls back to decimal interpretation; try gawk 'BEGIN {print 010}' vs. gawk 'BEGIN {print 08}'.
@mklement0 Interesting! I added that to the answer.

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.