I want to filter and format the output of ps -ax -o pid,command, but not sure what pipe to use for it.

I want to filter those lines matching a fixed string at a fixed position, just keep the pids for the matched lines, and output them as a space-separated list such as 1234 5678 33121.

I can trivially do the first step using | egrep 'regex', but the second step probably needs sed or something, and I can't work it out. Since sed (and awk) also handle regex filtering, I probably don't need grep.

Multiple space characters are fine, and sort order isn't important, so there's no need to trim the PIDs or order the lines. Example:

$ ps -ax -o pid,command

    0 [kernel]
    1 /sbin/init --
  255 /usr/local/sbin/check_status
  268 /sbin/devd -q
 1435 (unlinkd) (unlinkd)
 1974 sleep 60
 7414 /bin/sh /var/db/test/update.sh
21848 ps -ax -o pid,command
39207 /usr/local/sbin/syslog-ng -p /var/run/syslog-ng.pid

find all processes whose command begins /usr/ (ie lines matching /usr/ in chars 7-11 or the regex ^[0-9 ]{5}\s\/usr\/) and return their pids (or first 5 chars) on a single line space-separated. Output:

255 39207   (no \n's, amount of spacing unimportant).

I've tried but sed isn't the easiest command to figure out. How do I do it?


If you're willing to take all the digits of the pid you could use pgrep to do this for you:

pgrep -d " " -f ^/usr

will print a space separated list of all the PIDs of processes whose command starts with /usr

If you really want to use the ps command, awk would be a better tool than sed to do what you want. You could do it, with just the first 5 characters of the PID like:

ps -ax -o pid,command | awk '$2 ~ /^\/usr/ {printf( "%s ", substr($1,0,5));} END {print ""}'

This will check if the second field starts with /usr and if so print up to the first 5 characters of the first field followed by a space, then I threw in a newline at the end for good measure, but you could remove that if you don't want a newline even at the very end

As Giles pointed out, you'll probably never really want just the first 5 characters of a PID (that was probably me misreading the question) so the more useful answer using awk would be:

ps -ax -o pid,command | awk '$2 ~ /^\/usr/ {printf( "%d ", $1);} END {print ""}'
  • 1
    Eric, you just have beaten me by 5 seconds :)
    – heemayl
    Aug 29 '15 at 0:23
  • pgrep was what I needed - and the awk version will be insanely useful if I hit a variant that pgrep/pkill can't solve... which I just did: "kill all processes that match this regex and have a pid in this list". I might be able to solve it now, though, but any hints appreciated :)
    – Stilez
    Aug 29 '15 at 2:07
  • @Stilez if you're not opposed to a second grep, just pgrep regex | egrep pid1|pid2...
    – Jeff Schaller
    Aug 29 '15 at 12:25
  • Make that {printf "%d ", $1} to simply print the PID plus a space. Aug 29 '15 at 16:16
  • @giles agreed to get the whole PID it's in $1, but I had been thinking the OP was asking for just the first 5 chars of the PID (which is probably not really very useful) when they said " their pids (or first 5 chars)". So I was offering that as a way to get the first 5 chars, but I'll include your suggestion as it's probably more useful in general Aug 29 '15 at 17:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.