10

Suppose I have a ps command that looks like this:

ps -Ao args:80,time,user --sort time 

It will give me a "space" separated set of rows. A row might look like this

paulnath -bash 00:00:00

I would like to convince ps to delimit by commas(or tabs even!), such that it can be processed automagically by other languages. Please note that args will probably have spaces in it, so, awking by field won't per se work.

walkytalky
  • 9,453
  • 2
  • 36
  • 44
Paul Nathan
  • 39,638
  • 28
  • 112
  • 212

6 Answers6

18

You can use the following syntax to put your own delimiter:

ps -Ao "%U,%t,%a"
emx
  • 1,295
  • 4
  • 17
  • 28
  • 5
    The % is the so called AIX format descriptor. Not all ps columns have such a descriptor. For example rsz column does not have it. – Dmitrii I. May 04 '14 at 18:40
1

CODE

ps -Aco time,user,command | mawk NF=NF OFS=','

      # lower-case -o for basic columns
      # upper-case -O for info overloading

OUTPUT - (sample only, not identical to OP's)

TIME,USER,COMMAND
20:13.26,root,launchd
3:53.13,root,logd
0:32.95,root,UserEventAgent
0:04.87,root,uninstalld
6:58.58,root,fseventsd
0:02.48,root,mediaremoted
4:02.23,root,systemstats

I dunno what variant of ps OP might have, whether flags -Aco work or not - i can only speak about my experience on macos 12.4

————————————————

In fact, set OFS to anything delimiter you like - personally I usually love equal sign [ = ] as a field delimiter

  • individual field strings can go completely unquoted,

    • even if it has spaces, tabs, unicodes, even all sorts of random bytes
  • conversely, basically nothing needs to be escaped, even for single- or double-quotes,

    • except when field texts include [ = ] itself, then just find a random pair or triplet of bytes to escape [ = ]
  • reasonably safe choice when compared to just about any other ascii [[:punct:]], since it's among the chars least likely to have special meanings in shell or any regex engine, while still directly type-able from a QUERTY keyboard

mawk NF=NF OFS==
                \
                 yields
                /
0:00.03=root=colorsyncd
0:54.30=root=searchpartyd
0:00.57=_appleevents=appleeventsd
0:00.92=root=findmydeviced
0:30.52=_networkd=symptomsd
RARE Kpop Manifesto
  • 2,453
  • 3
  • 11
0

How about:

ps -Ao args:80,time,user --sort time | 
sed 's/\([[:digit:]]\{2\}:\)\{2\}[[:digit:]]\{2\}/,\0,/'

This is sensitive to the format, including the time, and assumes processes don't have commas. They can, but if you want to escape that it's obviously more complicated.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
0

Reorder your columns and you can handle spaces into command values:

ps -Ao time,user,args:80 --sort time | awk '{
  for (i=1; i<=NF; i++) {
    if(i==3) printf ","
    if (i<3){
      if(i > 1) printf ","
    
      printf "%s", $i
    }else if (i>=3){
      printf "%s ", $i
    }
  }
  printf "\n"
}'

Output:

enter image description here

Estuardolh
  • 111
  • 1
  • 6
0

You can combine multiple AIX FORMAT DESCRIPTORS (which allow printf-style formatting, but provide a limited subset of fields) and STANDARD FORMAT SPECIFIERS (which allow the full set of fields) to get any combination of fields with any separator:

ps -A -o "%p," -o rss -o ",%c,%a"
James Scriven
  • 7,784
  • 1
  • 32
  • 36
-1

You might want to get the information you need from /proc/[0-9]*/. I think you'll find it more programmatically accessible than the output of ps.

MarredCheese
  • 17,541
  • 8
  • 92
  • 91
Slartibartfast
  • 1,694
  • 9
  • 8