我正在由数百个其他用户共享的 Linux 集群上运行模拟。集群上安装了一个作业调度程序,用于确定谁在哪里运行,调度程序命令之一 ( showq
) 显示所有活动作业、空闲作业、阻止作业等的列表。我想处理该输出以确定诸如在任意一点运行作业的唯一用户数量。以下是 的一些输出示例showq -r
,其中显示了正在运行的作业:
active jobs------------------------
JOBID S PAR EFFIC XFACTOR Q USERNAME GROUP MHOST PROCS REMAINING STARTTIME
123456 R bas ----- 1.0 - user_X group_A n1 8 4:00:00 Fri Sep 19 17:25:05
123457 R bas ----- 1.0 - user_Y group_B n2 16 4:00:00 Fri Sep 19 17:25:05
123458 R bas ----- 1.0 - user_Y group_B n3 1 4:00:00 Fri Sep 19 17:25:05
123459 R bas ----- 1.0 - user_X group_A n4 1 4:00:00 Fri Sep 19 17:25:05
123460 R bas ----- 1.0 - user_X group_A n5 2 4:00:00 Fri Sep 19 17:25:05
123461 R bas ----- 1.0 - user_Z group_A n6 4 4:00:00 Fri Sep 19 17:25:05
......
5000 active jobs
具体来说,我想计算:
- 运行作业的唯一用户的数量,以及每个用户正在运行的作业数量(我也想对组执行相同的操作,但是一旦您对用户执行了此操作,这将是微不足道的)
PROCS
用户/组占用的处理器核心数 ( )- 用户/组正在运行的串行 (
PROC=1
) 和并行 ( ) 作业数PROC>1
我可以在 Python 中相当轻松地完成此操作,但我想使用awk
/sed
或其他 Linux 命令的某种组合来完成它。圆滑的俏皮话让我很高兴:-)
答案1
您需要做的第一件事是从 的输出中删除不需要的行showq -r
,即表示活动作业等的行。这可以使用 来完成showq -r | sed '1,2d' |sed '$d'
,或者您可以使用grep
描述部分数据行的正则表达式 - 例如grep "----"
在这种情况下,如果 的值EFFIC
始终为 ,则可能有效----
。一旦您获得了仅包含数据行的文件,您可以使用associative arrays in awk
完成剩下的魔法。
#!/bin/awk
{
proc_count[$7] = proc_count[$7] + $10;
if ($10 > 1) { multi_proc[$7]++; } else { single_proc[$7]++; }
}
END {
for (foo in proc_count) { print foo, proc_count[foo], multi_proc[foo], single_proc[foo] }
}
如果运行上面的脚本,您会注意到没有显示任何串行处理器计数user_z
。那是因为我试图节省行数并且没有0
在那里打印 a 。我将让您自行添加错误检查并美化输出。
答案2
首先存储以下脚本并chmod +x
为其命名job_processor.awk
:
#!/usr/bin/gawk -f
## $7 username
## $8 groupname
## $10 procs
{
if ( $10 == 1 )
printf ("username: %s and groupname: %s are serial!\n",$7,$8);
else if ( $10 > 1 )
printf ("username: %s and groupname: %s are parallel!\n",$7,$8);
printf ("username: %s and groupname: %s with procs: %d!\n",$7,$8,$10);
}
你必须使用以下格式:
cat jobs |./job_process.awk |sed '1,2d' |sed '$d'
输出是:
username: user_X and groupname: group_A are parallel!
username: user_X and groupname: group_A with procs: 8!
username: user_Y and groupname: group_B are parallel!
username: user_Y and groupname: group_B with procs: 16!
username: user_Y and groupname: group_B are serial!
username: user_Y and groupname: group_B with procs: 1!
username: user_X and groupname: group_A are serial!
username: user_X and groupname: group_A with procs: 1!
username: user_X and groupname: group_A are parallel!
username: user_X and groupname: group_A with procs: 2!
username: user_Z and groupname: group_A are parallel!
username: user_Z and groupname: group_A with procs: 4!