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

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.