Industry guru Dave Taylor offers tech support on technical and business topics, including iPhone, iPod, Microsoft Windows, Sony PSP, cellphones, online advertising, CSS, Web design, business, Unix, Linux, SEO, Mac OS X, and shell script programming.     


Extracting the correct column with "ps" and "awk"

A reader writes:
Every *nix implementation is different. But I'm seeing some some shared behavior between HPUX and Solaris with script #52 Killing Processes by Name. The problem is that the script is trying to kill the "tty" name, instead of the pid.

Wish I understood the following line better so I could make it grab the right columns. :-\

pids=$(ps cu -U $user | awk "/ $1$/ { print \$2 }")


Dave's Answer:
Let's tackle this backwards, shall we?

The last line assigns the result of the shell escaped ps | awk pipe to a shell variable called "pids" (this is indicated by the $( and ) pair).

Within the shell, the ps command lists all processes, with the two flags 'c' and 'u', which change the command name to be just the executable name, and display useful information too, and the '-U user' flag limits results to just the specified user (in case more than one user has processes running on the tty device).

The output is expected to look like this:

$ ps -cu -U taylor
USER     PID %CPU %MEM      VSZ    RSS  TT  STAT STARTED      TIME COMMAND
taylor   222   4.3 -3.9   329032  81652  ??  Ss   Thu08PM 108:00.19 WindowServer
taylor  1760   3.3 -0.4   202792   8792  ??  R    10:09AM   0:09.09 Terminal
taylor  1162   1.0 -1.2   269288  25800  ??  S    Sat08AM  29:42.57 iChat
taylor   714   0.4 -1.3   242220  27564  ??  S    Fri08AM  23:57.56 iTunes
taylor   287   0.0 -0.6   208284  13468  ??  S    Thu08PM   1:53.66 Dock
(this is a subset of the output)

Now you can see that if we search for a specific pattern, we'll match all lines that are associated with a specific process name. This could be done with grep, but using awk is useful because we can then control which of the output fields is listed too (we only want the PID, field #2). That's what the second part of the pipe does.

The problem you're seeing is that your version of Unix isn't returning the same results for the ps -cu -Uuser command. That being the case, you're probably seeing output like this:

  PID  TTY       TIME COMMAND
 10361 ttyrb     0:00 sleep
In which case you'll want to change the second part of the awk statement to extract the first field not the second (since the PID is in field one now). It would look like this:
pids=$(ps cu -U $user | awk "/ $1$/ { print \$1 }")
Try that and see if you have better results!

Related Shell Script Programming articles:
✔   Secretly capture screenshots on my Mac?
When I used to work on a Linux system, there was a utility we had that would let me take screen captures every...
✔   Parsing "id" strings in a Shell Script?
Hello Dave. I need a Bash shell script that creates a directories with the group names automatically when user logs in to the...
✔   Copy and Paste from the Mac OS X Command Line?
I am constantly running commands in Terminal.app on my MacBook and then copying and pasting the results into email messages or documents. Yes,...
✔   Script to test line lengths for Twitter compatibility?
I've been tasked with writing a series of tweets for a Black Friday marketing campaign and am finding it a bit tricky because...
✔   Shell script to convert lowercase to title case?
As part of a project I'm working on, I find myself deep in a Linux shell script, needing to have a subroutine that...

Let's stay in touch!
Sign up for my weekly AskDaveTaylor Newsletter and you'll receive even more tech and gadget help right to your inbox, along with exclusive news and industry updates. It's good stuff. I promise!
    Enter your name: and your email addr:  









Reader Comments To Date: 4

linuxbug said, on December 22, 2005 7:36 AM:

check the output of "who". Now how will you kill all the processes by specific IP Address of a specific user.

Dave Taylor said, on December 22, 2005 7:48 AM:

An interesting question. Sounds like you need two 'grep' commands in a row. Here's what "who" looks like:

$ who
dtint ttyp2 Dec 20 01:23 (71.138.150.180)
dtint ttyp3 Dec 22 14:44 (67.165.197.92)

So the first step would be to map the IP address to the tty device. Let's say I was interested in the first login... so I could do something like this:

tty="$(who | grep 71.138.150.180 | head -1 | awk '{print $2}')"

now I have in the 'tty' variable the device name. The next step is to simply feed that to the ps command, utilizing the "-t" flag. Well, not quite, because 'who' returns 'ttyp2", but we actually want "p2" for the "ps" command, so we'd need a slight tweak:

tty="$(echo $tty | sed 's/tty//')"

now we're ready:

ps -t $tty

The rest I'll leave as an exercise to the reader.:-)

TJAIN said, on February 13, 2007 8:54 AM:

I have a file that looks like

161 16385 11_15
161 16388 11_15
161 16393 11_15
161 16399 11_15
159 94306 3_13
159 94308 3_13
159 94310 3_13

How do I extract first two columns based on the third column (all columns with 11_15), so forth?

Dave Taylor said, on February 13, 2007 9:20 AM:

That should be easy. Something like this

for matchingline in $(grep "11_15" inputfile)
do
field1=$(echo $matchingline | cut -f1)
done

etc.

Starbucks coffee cup I do have a lot to say, and questions of my own for that matter, but first I'd like to say thank you, Dave, for all your helpful information by buying you a cup of coffee!

I do have a comment, now that you mention it!











I will never send you any unsolicited email. Ever.






Check This Out Too...

 
Look for Answers
Need Help? Ask Dave Taylor!


Follow Me on Pinterest

Find Me on Google+
ADT on G+
© 2002 - 2013 by Dave Taylor. All Rights Reserved.

Note: This web site is for the purpose of disseminating information for educational purposes, free of charge, for the benefit of all visitors. We take great care to provide quality information. However, we do not guarantee, and accept no legal liability whatsoever arising from or connected to, the accuracy, reliability, currency or completeness of any material contained on this web site or on any linked site. Further, please note that by submitting a question or comment you're agreeing to my terms of service, which are: you relinquish any subsequent rights of ownership to your material by submitting it on this site. My lawyer says "Thanks".
"Ask Dave Taylor®" is a registered trademark of Intuitive Systems, LLC.