Bash – more elegant way to count words and assign that count to variables

awkbashshell-script

I have a script:

#!/bin/bash

/root/xiotech status > xiostatus.tmp
SyncCount=$(grep -c Sync xiostatus.tmp)
PauseCount=$(grep -c paused xiostatus.tmp)
CopyingCount=$(grep -c Copying xiostatus.tmp)

if [ "$SyncCount" -eq "11" ]
then echo All 11 mirrors are in sync.

else echo $PauseCount mirrors are paused and $CopyingCount mirrors are syncing.
fi

rm -f xiostatus.tmp

Is there a more elegant way to count and "variable-ize" those counts using something like awk? In this case the file is tiny so it's not a big deal, but if the file were 900mb, it would take a lot of extra cycles to go through it 3 times…

Best Answer

awk can replace the entire script pretty easily:

#!/usr/bin/awk -f

/Sync/ {SyncCount++}
/paused/ {PauseCount++}
/Copying/ {CopyingCount++}

END {
    if(SyncCount == 11)
        print "All 11 mirrors are in sync."
    else
        print (+PauseCount) " mirrors are paused and " (+CopyingCount) " mirrors are syncing."
}

The (+var) is to force awk to treat the variable as a number (so it will output 0 if the variable was unset). You can also use a BEGIN block to set all the variables to 0 initially:

BEGIN {
    SyncCount = PauseCount = CopyingCount = 0
}

Stick that in a file and run awk -f /path/to/the/script.awk xiostatus.tmp. If you don't need the temporary file, you can even do /root/xiotech status | awk -f /path/to/the/script.awk.

If you set the execution bit on the awk script, you can call it as a standalone executable: /path/to/the/script.awk xiostatus.tmp, or /root/xiotech status | /path/to/the/script.awk.

Related Question