0

I'm trying to sum all bytes in "RX packets" lines of an ifconfig | grep "RX packets" output.

How do I do that?

Here's my code

#!/usr/lib/env bash

clear

result=0

while read i; do

    line=${i##*'bytes'} | awk '{print $1;}' 
    
    (( "$result"+="$line" ))

    echo "$result"

done <<< "$(ifconfig | grep "RX packets")"

Also: How should I extract those lines of bytes in a better way, doing "$(ifconfig | grep "RX packets")" and then line=${i##*'bytes'} | awk '{print $1;}' seems so ugly and complicated

if config | grep "RX packets" my output:

        RX packets 7817232  bytes 9337993347 (9.3 GB)
        RX packets 1240058  bytes 83114376 (83.1 MB)
        RX packets 0  bytes 0 (0.0 B)
        RX packets 188707  bytes 27682805 (27.6 MB)

Desired result - sum of all bytes:

9337993347 + 83114376 + 27682805
12
  • In the line line=${i##*'bytes'} | awk '{print $1;}', what input do you expect awk to be seeing? Commented Aug 30, 2022 at 15:16
  • It would be handy if you provided sample input and desired output, since the output of ifconfig varies by platform. Commented Aug 30, 2022 at 15:18
  • The number after the word bytes in ifconfig | grep "RX packets" Commented Aug 30, 2022 at 15:18
  • You are missing a command substitution in the assignment to line. Commented Aug 30, 2022 at 15:20
  • 1
    This whole thing should be a single awk script, not a shell script that uses awk to do minimal processing on each line. Commented Aug 30, 2022 at 15:21

3 Answers 3

3

Using the shell to do arithmetic with a while/read loop is slow and clunky. You could simply do:

ifconfig | awk '/RX packets/{ s += $5 } END {print s}'

(This assumes a particular format for the output of ifconfig, so this will likely fail if you use it on a different platform.)

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

Comments

2

When assigning to a variable, even inside an arithmetic expression, use the variable name without the dollar sign.

When reading from a command list, use process substitution rather than a here string.

Also, you don't need awk, you can remove the substring similarly to how you removed the other part.

#! /bin/bash
result=0

while read line; do

    line=${line##*bytes}  # Remove everything up to bytes.
    line=${line%(*}       # Remove everything starting from (.
    
    (( result+=line ))
done < <(ifconfig | grep "RX packets")
echo $result

3 Comments

This is correct, but is bad advice. This problem is best solved with awk.
I'd probably use Perl instead. How is "best" defined?
lol. A very good argument could be made that "best" == "perl"! Doing it directly in the shell like this might be good exercise, though.
0

Alternatively, with sed and bash:

bytes=$(ifconfig | sed -n 's/.*RX packets.*bytes \([0-9]*\).*/\1/p')
echo $(( ${bytes//$'\n'/+} ))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.