dig_123 dig_123 - 6 months ago 23
Linux Question

How to control AWK on which output field separators to change and which not

I have top 5 CPU utilizing processes with this command:

ps -eo pcpu,pmem,pid,ppid,cmd | sort -k 1,1nr | head -5


The Output:

0.2 0.0 5037 1 /sbin/hpHelper -I0
0.1 0.0 5567 1 cmahostd -p 15 -s OK -l /var/log/hp-snmp-agents/cma.log
0.1 0.0 5839 1 cmanicd
0.0 0.0 10 1 [watchdog/2]
0.0 0.0 10689 1 cmasm2d -p 30 -l /var/log/hp-snmp-agents/cma.log


The fields are
CPU%,MEMORY%,PID,PPID,COMMAND


I want the output to be comma separated with timestamp in the beginning of each line. However the last field which is
command
field should not be comma separated. I'm using the below:

ps -eo pcpu,pmem,pid,ppid,cmd | sort -k 1,1nr | head -5 | awk -v dt=$(date +'%Y,%m,%d,%H,%M,%S') -v OFS=, '{$1=dt OFS $1; print $0}'


which gives me an output:

2016,05,22,00,26,19,0.2,0.0,5037,1,/sbin/hpHelper,-I0
2016,05,22,00,26,19,0.1,0.0,5567,1,cmahostd,-p,15,-s,OK,-l,/var/log/hp-snmp-agents/cma.log
2016,05,22,00,26,19,0.1,0.0,5839,1,cmanicd
2016,05,22,00,26,19,0.0,0.0,10,1,[watchdog/2]
2016,05,22,00,26,19,0.0,0.0,10689,1,cmasm2d,-p,30,-l,/var/log/hp-snmp-agents/cma.log


Whereas Output I'm expecting:

2016,05,22,00,26,19,0.2,0.0,5037,1,/sbin/hpHelper -I0
2016,05,22,00,26,19,0.1,0.0,5567,1,cmahostd -p 15 -s OK -l /var/log/hp-snmp-agents/cma.log
2016,05,22,00,26,19,0.1,0.0,5839,1,cmanicd
2016,05,22,00,26,19,0.0,0.0,10,1,[watchdog/2]
2016,05,22,00,26,19,0.0,0.0,10689,1,cmasm2d -p 30 -l /var/log/hp-snmp-agents/cma.log


How to modify the script to achieve this ?

Answer

Replace cat file with your ps command:

$ cat file | sort -k 1,1nr |
    awk -v dt=$(date +'%Y,%m,%d,%H,%M,%S') -v OFS=, 'NR<6{cmd=$0; sub(/^[[:space:]]*([^[:space:]]+[[:space:]]+){4}/,"",cmd); print dt,$1,$2,$3,$4,cmd}'
2016,05,21,18,37,49,0.2,0.0,5037,1,/sbin/hpHelper -I0
2016,05,21,18,37,49,0.1,0.0,5567,1,cmahostd -p 15 -s OK -l /var/log/hp-snmp-agents/cma.log
2016,05,21,18,37,49,0.1,0.0,5839,1,cmanicd
2016,05,21,18,37,49,0.0,0.0,10,1,[watchdog/2]
2016,05,21,18,37,49,0.0,0.0,10689,1,cmasm2d -p 30 -l /var/log/hp-snmp-agents/cma.log

Note you don't need to use head, awk can handle selecting the first 5 lines.