我正在尝试解析此输出:
$ top -b -d 1 -n 1 -p 5997
top - 08:54:39 up 86 days, 2:42, 1 user, load average: 0.00, 0.03, 0.05
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
Cpu(s): 8.9%us, 1.5%sy, 0.0%ni, 89.5%id, 0.1%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 3869696k total, 2010912k used, 1858784k free, 162404k buffers
Swap: 0k total, 0k used, 0k free, 736120k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5997 tomcat7 20 0 1209m 534m 6940 S 0.0 14.2 14:40.85 java
$
我的预期输出是:
534m
所以我想从second last line
那里得到6th
领域。(最后一行是空行,因此我正在查看second last
行)
这是我的解决方案:
$ top -b -d 1 -n 1 -p 5997 | awk 'NF > 0' | awk 'END {print $6}'
539m
我首先删除空白行,然后从最后一行中提取第 6 个字段。它有效。完善!!!
问题:
我不喜欢使用 2 根awk
管。因此,必须有一个优雅的解决方案来使用单个awk
语句来实现相同的目的。你能帮我吗?
即使是Perl
单行本也会有所帮助。
您当然可以组合 top 和 awk 来获取您想要的任何文本部分。 但对于您的要求,我认为ps
更适合您:
ps -h --format rss <PID>
这将为您提供相同的数字 Kilobytes
. 如果你喜欢在最后有m
,你可以/1024
.
编辑
即使 Jonta 报告了版本差异问题。我仍然不认为解析 top 的输出以获得内存使用情况是最好的方法。这将是通用解决方案:
grep -oP 'VmRSS:s*K.*' /proc/<PID>/status
这是我使用上述命令和ps
命令的输出:
kent$ ps -h -o rss 25579
405304
kent$ grep -oP 'VmRSS:s*Kd*' /proc/25579/status
405304
您可以轻松地用其他功能强大的工具替换grep
,例如BC,awk...如果您愿意,可以mb
单位。
你来了:
awk 'now { print $6; exit } $1 == "PID" { now = 1 }'
解释:
- 针对每行输入评估命令
- 变量
now
未设置,因此默认情况下不执行now { ... }
块 - 当第一个字段是"PID"时,我们将
now
设置为1,这样当下一行到来时,now { ... }
块将被执行 - 在
now { ... }
块中,我们打印第 6 个字段并退出以停止处理
这是我用awk
做到这一点的方式
awk '/PID/ {getline;print $6}'
这将搜索带有PID
的行,获取下一行并打印字段$6
top -b -d 1 -n 1 -p 5997 | perl -anE '@r=@F if @F; END{ say $r[5] }'
Perl 遍历行并将列值存储在 @F
中。它还将相同的值存储到数组@r
但仅在存在实际值时(对于非空行)。在末尾输出最后一个非空行的列。
获取倒数第二行的简单(但通用)方法:
$ echo -e "abcndefnijk" | tail -2 | head -1