I am trying to essentially run a command on each line of a file. Below is what I have so far. I want to be able to take each line, take the last column from it, run a command on the integer and if it doesn't equal zero, echo the full line. I seem to be running into errors and can't seem to figure out where.
#!/bin/bash
IFS=\n
file=`cat /proc/user_beancounters`
for line in "$file"
do last_col=`echo "$line" | awk '{print $(NF)}'` if [ $last_col -ne 0 ]; then echo $last_col fi
doneContents of /proc/user_beancounters:
Version: 2.5 uid resource held maxheld barrier limit failcnt
34579: kmemsize 28694400 33435648 67108864 67108864 0 lockedpages 0 0 64 64 0 privvmpages 473539 581717 786432 786432 176 shmpages 26821 26821 43008 43008 0 dummy 0 0 9223372036854775807 9223372036854775807 0 numproc 113 159 500 500 0 physpages 199504 208572 524288 524288 0 vmguarpages 0 0 98304 98304 0 oomguarpages 188782 191010 6144 6144 0 numtcpsock 35 37 160 160 0 numflock 8 11 100 100 0 numpty 1 1 200 200 0 numsiginfo 0 36 500 500 0 tcpsndbuf 616080 650960 8388608 8388608 0 tcprcvbuf 577800 621600 8388608 8388608 0 othersockbuf 108664 135616 8388608 8388608 0 dgramrcvbuf 0 16184 8388608 8388608 0 numothersock 116 128 500 500 0 dcachesize 8375457 8388258 8388608 8388608 0 numfile 2627 2915 8192 8192 0 dummy 0 0 9223372036854775807 9223372036854775807 0 dummy 0 0 9223372036854775807 9223372036854775807 0 dummy 0 0 9223372036854775807 9223372036854775807 0 numiptent 168 168 9999999 9999999 0In the above example, I want the script to essentially pick out that "privvmpages" has failed more than once, and therefore echo the line:
privvmpages 473539 581717 786432 786432 176Or if possible, just the name "privvmpages" and the number "176"
Thanks in advance
1 Answer
Using bash
The following works:
while IFS= read -r line
do last_col=`echo "$line" | awk '{print $(NF)}'` if [[ $last_col =~ ^[[:digit:]]+$ && "$last_col" -ne 0 ]]; then echo $line fi
done </proc/user_beancountersNotes:
The command
IFS=\nsetsIFSto the lettern. This is not what you want. If you really wantIFSto be a newline, use insteadIFS=$'\n'.$last_col =~ ^[[:digit:]]+$This test assures that
last_colis an integer. This has the effect of skipping over the header lines.
Using awk
Looping over the lines of a file is something that awk does naturally. The above code can be replaced by:
awk 'NR > 2 && $NF != 0' /proc/user_beancountersNotes:
NR>2The first two lines of the file are headers. This skips over them.
$NF != 0This selects lines whose last field is non-zero.
with no explicit command associated with the above two conditions,
awkwill print the whole line.
Alternatively, if you want to print just the first and last column, use:
awk 'NR>2 && $NF != 0 {print $1,$NF}' /proc/user_beancounters 2