tags:

views:

992

answers:

5

I want to do this:

  1. run a command
  2. capture the output
  3. select a line
  4. select a column of that line

Just as an example, let's say I want to get the command name from a $PID (please note this is just an example, I'm not suggesting this is the easiest way to get a command name from a process id - my real problem is with another command whose output format I can't control).

If I run ps I get:


  PID TTY          TIME CMD
11383 pts/1    00:00:00 bash
11771 pts/1    00:00:00 ps

Now I do ps | egrep 11383 and get

11383 pts/1    00:00:00 bash

Next step: ps | egrep 11383 | cut -d" " -f 4. Output is:

<absolutely nothing/>

The problem is that cut cuts the output by single spaces, and as ps adds some spaces between the 2nd and 3rd columns to keep some resemblance of a table, cut picks an empty string. Of course, I could use cut to select the 7th and not the 4th field, but how can I know, specially when the output is variable and unknown on beforehand.

A: 

Getting the correct line (example for line no. 6) is done with head and tail and the correct word (word no. 4) can be captured with awk:

command|head -n 6|tail -n 1|awk '{print $4}'
soulmerge
+5  A: 

I think the simplest way is to use awk. Example:

$ echo "11383 pts/1    00:00:00 bash" | awk '{ print $4; }'
bash
brianegge
For compatibility with the original question, `ps | awk "\$1==$PID{print\$4}"` or (better) `ps | awk -v"PID=$PID" '$1=PID{print$4}'`. Of course, on Linux you could simply do `xargs -0n1 </proc/$PID/cmdline | head -n1` or `readlink /proc/$PID/exe`, but anyhow...
ephemient
+1  A: 

One easy way is to add a pass of tr to squeeze any repeated field separators out:

$ ps | egrep 11383 | tr -s ' ' | cut -d ' ' -f 4
unwind
I like this one, looks like `tr` is more lightweight than `awk`
flybywire
I would tend to agree, but that might also be because I haven't learned awk. :)
unwind
A: 

try

ps |&
while read -p first second third fourth etc ; do
   if [[ $first == '11383' ]]
   then
       echo got: $fourth
   fi       
done
James Anderson
Dennis Williamson
way too complicated
flybywire
A: 

Instead of doing all these greps and stuff, I'd advise you to use ps capabilities of changing output format.

ps -o cmd= -p 12345

You get the cmmand line of a process with the pid specified and nothing else.

This is POSIX-conformant and may be thus considered portable.

Pavel Shved