LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   [SOLVED]Wierd AWK behavior / AWK not reading first line. (https://www.linuxquestions.org/questions/linux-newbie-8/%5Bsolved%5Dwierd-awk-behavior-awk-not-reading-first-line-4175438774/)

Involar 11-26-2012 10:36 AM

[SOLVED]Wierd AWK behavior / AWK not reading first line.
 
Hello,

I'm having issues with parsing PS output with awk. For some reason the first line is always ignored.

:~$ ps -e -o pid,rss,command | grep tty
850 864 /sbin/getty -8 38400 tty4
854 856 /sbin/getty -8 38400 tty5
861 860 /sbin/getty -8 38400 tty2
862 852 /sbin/getty -8 38400 tty3
864 852 /sbin/getty -8 38400 tty6
923 864 /sbin/getty -8 38400 tty1
2133 836 grep --color=auto tty
:~$ ps -e -o pid,rss,command | grep tty | while read line; do awk '{print $1}'; done
854
861
862
864
923
2135


As you can see the first line (pid in this case) is missing from the output. Is there a way to fix it without having to first save results to a file and then parse the file with awk? Thanks

druuna 11-26-2012 11:14 AM

You don't need the grep and the while loop, have a look at this:
Code:

ps -e -o pid,command | awk '/tty[0-9]/ { print $1 }'

Involar 11-26-2012 11:47 AM

Hello,

This was just an example of awk not doing its job. I need the while loop because the script im writing is examining each line and does an action based on what the line contains. Basic example:
:~$ ps -e -o pid,rss,command | grep tty
850 864 /sbin/getty -8 38400 tty4
854 856 /sbin/getty -8 38400 tty5
861 860 /sbin/getty -8 38400 tty2
862 852 /sbin/getty -8 38400 tty3
864 852 /sbin/getty -8 38400 tty6
923 864 /sbin/getty -8 38400 tty1

awk needs to select $2 and if its > 850 a kill -9 needs to performed and logged in a separate log file.

rosehosting.com 11-26-2012 12:08 PM

Try with the following one-liner:
Code:

while read pid; do echo "$pid"; done <<< $(ps -e -o pid,rss,command | awk '/tty[0-9]/ { if($2>850) print $2 }')

Quote:

Originally Posted by Involar (Post 4837362)
Hello,

This was just an example of awk not doing its job. I need the while loop because the script im writing is examining each line and does an action based on what the line contains. Basic example:
:~$ ps -e -o pid,rss,command | grep tty
850 864 /sbin/getty -8 38400 tty4
854 856 /sbin/getty -8 38400 tty5
861 860 /sbin/getty -8 38400 tty2
862 852 /sbin/getty -8 38400 tty3
864 852 /sbin/getty -8 38400 tty6
923 864 /sbin/getty -8 38400 tty1

awk needs to select $2 and if its > 850 a kill -9 needs to performed and logged in a separate log file.


Involar 11-26-2012 12:40 PM

Hello, i managed to achieve it with the following :
ps -e -o pid,rss,command | grep -v grep | grep tty |
awk '{
if ( $2 > "850" ) {
print( "Killing",$1 )
system( "kill -9 "$1 )
system( "echo `date` " $3 " >> /home/asdf/logs/kill.log")
}
}'

Thanks for the help !

goossen 11-27-2012 04:38 AM

Here is a tip to avoid the "grep -v grep" part:
Code:

ps -e -o pid,rss,command | grep [t]ty

grail 11-27-2012 08:14 AM

To answer the original question AWK not reading first line, this is completely correct, however, you did tell your script not to pass the first line to awk.

We can assume that the data prior to the while loop is always in tact as the ps and grep work without issue.
So, if we look at just the while loop portion:
Code:

while read line; do
    awk '{print $1}';
done

From here we see that the first read of the data is performed by the read function and hence the first line is now stored in the variable 'line', ie line='850 864 /sbin/getty -8 38400 tty4'.

Then looking at the second line of code, the glaring omission would be that awk has not been delivered any input, file name or string, so it goes out to the next level of input ... stdin

Here it finds the rest of your data waiting to be processed, which it does, starting at line 2 as there is no longer line 1 available due to it already being read.

There are of course better solutions, some already offered, but to solve the problem you asked, you would need to feed the awk the individual lines you are reading in the loop:
Code:

ps -e -o pid,rss,command | grep tty | while read line; do awk '{print $1}' <<< "$line"; done

pan64 11-27-2012 08:35 AM

what about pgrep -f 'tty[0-9]' ?

Involar 11-27-2012 01:04 PM

Thanks for the replies. Appreciate it and indeed grail's solution worked.

grail 11-28-2012 10:53 AM

See my signature for how to mark as SOLVED.


All times are GMT -5. The time now is 10:36 AM.