Help with AWK command

I have a problem with awk that I can’t seem to solve.
I get snmp data from my router to view data usage. this is a text file that is replaced every 24 hours and file is updated every hour. I get a negative number that shows up and it skews the data on my little web server.

cat 08-May-25-wrls0ta.txt
372963176
375429610
377839519
380349356
382724138
385122436
392181488
397911741
400312606
404918306
407109524

cat 08-May-25-wrls0ta.txt | awk ‘NR > 1 { print ($1 - prev)/1000000 } { prev = $1 }’
2.46643
2.40991
2.50984
2.37478
2.3983
7.05905
5.73025
2.40087
4.6057
2.19122
-407.11

I see counter wrap-around (e.g., a 32-bit counter reaching its maximum value and resetting to zero). Weird. The following command seems to solve it you can hide the values if this happens:

cat 08-May-25-wrls0ta.txt | awk 'NR > 1 { diff = $1 - prev; if (diff < 0) { diff += 4294967296; } print diff / 1000000; } { prev = $1; }'

(0 - 407109524) / 1000000 = -407.11 so your source files seem to just have a trailing newline.

I’ve never used AWK but asked GROK to modify the command to also exclude blank lines.

It suggested the following command.

awk ‘$1 != “” && NR > 1 { print ($1 - prev)/1000000 } { prev = $1 }’

Try using something else like a python or JS script instead of using Awk.

If you have Python3

cat 08-May-25-wrls0ta.txt | python3 -c $'import sys\nprev = None\nWRAP_CONST = 4294967296\nfor line in sys.stdin:\n  current = int(line.strip())\n  if prev is not None:\n    diff = current - prev\n    if diff < 0:\n      diff += WRAP_CONST\n    print(f\'{diff / 1000000:.6f}\')\n  prev = current'

NodeJS

cat your_data_file.txt | node -e '
// Process SNMP counter data with 32-bit rollover handling
const readline = require("readline");
const DIVISOR = 1000000;
const WRAP_CONST = 4294967296; // 2^32

let prev = null;
const rl = readline.createInterface({
  input: process.stdin,
  crlfDelay: Infinity
});

rl.on("line", (line) => {
  if (!line.trim()) return;
  const current = parseInt(line.trim(), 10);
  
  if (prev !== null) {
    let diff = current - prev;
    if (diff < 0) diff += WRAP_CONST;
    console.log((diff / DIVISOR).toFixed(6));
  }
  
  prev = current;
});'

For anyone finding this thread needing help with awk.
awk cheat sheet : https://www.pement.org/awk/awk1line.txt

AFAICT here’s nothing wrong with the awk command, therefore you’ve got non-printing junk at the end of the file. Yes, I get the same result if I put a ^Z at the end of the file.

If it’s not convenient to get a clean file, you could add /\032/ {next} to the beginning of the awk expression:

cat 08-May-25-wrls0ta.txt | awk '/\032/ {next} NR > 1 { print ($1 - prev)/1000000 } { prev = $1 }'

In AWK you can match on a regex. If you match the non-empty string it’ll work:

cat 08-May-25-wrls0ta.txt | awk '! /^\s*$/ && NR > 1 { print ($1 - prev)/1000000} { prev = $1 }'
2.46643
2.40991
2.50984
2.37478
2.3983
7.05905
5.73025
2.40087
4.6057
2.19122

Edit: merged the two AWK expressions.
Edit 2: Added NR > 1

The above only works if there are empty lines at the end, if the occur in the middle you need /^\s*$/ on your second expression too:

awk '! /^\s*$/ && NR > 1 { print ($1 - prev)/1000000}  /^\s*$/ { prev = $1 }'```