我正在处理需要解析ps
命令返回的数据的脚本。在Redhat / Centos上,我知道很容易指定列分隔符,但使用BSD version of PS时,它并不那么简单。
我知道可以使用awk
,sed
或tr
替换任何字符的空格,但可以说格式为args
或{{1在中间的某个地方,输出将是:
comm
正如您所看到的,$ ps -o pid,ppid,args,user | head
PID PPID ARGS USER
60140 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe
60144 60141 -bash jdoe
55574 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe
55576 55575 -bash jdoe
20710 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe
20712 20711 -bash jdoe
66703 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe
66707 66704 -bash jdoe
66881 494 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server login -fp jdoe
列中的数据可以包含空格,这会使整个事情失效。
真的很烦人,我实际上找到了一个似乎工作得很好的解决方案,而不必像输出那样放置args
之类的东西,但我无法记住解决方案,或者再次找到它
我在想,也许可以使用列标题行来确定列的宽度,因为标题与列数据对齐,但我确信这比解决方案更简单。这一点。
任何帮助将不胜感激。谢谢!
答案 0 :(得分:0)
ps -o pid,ppid,args,user \
awk -v Rpl='_' '
# line but the header
NR > 1 {
p = $1
P = $2
u = $NF
A = $0
sub( "^[[:blank:]*" p "[[:blank:]*" P "[[:blank:]*", "", A)
sub( "[[:blank:]*" u "[[:blank:]*$", "", A)
gsub( " ", Rpl, A)
# recreate the line
$0 = sprintf( "%d\t%d\t%s\t%s\n", p, P, A, u)
}
# print the line
7
'
注意:
\t
作为新的分隔符,可以是其他任何内容。答案 1 :(得分:0)
好吧,既然你的bsd ps
不支持我之前的答案中建议的--libxo
选项,你可以使用经典的bash方法,将间隔的args放在最后。
然后,您可以使用循环读取数组中的整个ps输出,然后您可以通过调整相应数组项的打印以任何顺序打印任务。
但是对于"解析"你需要在最后保持间隔的args。对于打印,您只需按不同顺序打印数组。
请参阅此测试,并注意数组元素No7,11,15中的空格:
$ while read -r pid ppid user args;do \
psdata+=( "$pid" "$ppid" "$user" "$args" ); \
done< <(ps -o pid,ppid,user,args)
$ declare -p psdata #let's ask bash to print the array for us
declare -a psdata=([0]="PID" [1]="PPID" [2]="USER" [3]="COMMAND" [4]="769" \
[5]="1" [6]="root" [7]="/usr/libexec/getty Pc ttyv0" [8]="770" [9]="1" \
[10]="root" [11]="/usr/libexec/getty Pc ttyv1" [12]="771" [13]="1" [14]="root" \
[15]="/usr/libexec/getty Pc ttyv2" [16]="772" [17]="1" [18]="root" \
# more items here
答案 2 :(得分:-1)
PS实用程序最新FreeBSD11有--libxo
选项,可用于格式化xml,text,json等中ps
的输出。虽然此选项在ps实用程序中不可用较早的bsd(即openbsd 6或freebsd小于11)。
如果--libxo可用,则可以使用ps --libxo json
,然后使用jq
检索所需的值,或使用sed
等其他工具。
参见此测试:
$ ps --libxo json -o pid,args |tr '}' '\n' |sed 's/["{:]//g;s/arguments//g;s/pid//g;s/^,//g'
804,-csh (csh)
813,dbus-launch --sh-syntax --exit-with-session
816,xinit /usr/local/etc/xdg/xfce4/xinitrc
817,X 0 (Xorg)
819,sh /usr/local/etc/xdg/xfce4/xinitrc
825,xfce4-session
.....................................................
你可以进一步cut
格式化的stram并根据逗号分隔符提取字段(即输出|cut -d, -f2
上面的管道只会给你args)
如果你知道如何使用jq你不需要所有这些管道和seds,你可以直接从json流中提取字段。
此外,您可以查看man xo_parse_args
以获取有关ps的--libxo
选项的更多选项。