请教关于awk的一个循环问题(已完成)

sh/bash/dash/ksh/zsh等Shell脚本
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

请教关于awk的一个循环问题(已完成)

#1

帖子 wuy069 » 2012-12-14 19:38

有一个qhost.e的文件,内容如下,
HOSTNAME ARCH NCPU LOAD MEMTOT MEMUSE SWAPTO SWAPUS
-------------------------------------------------------------------------------
global - - - - - - -
compute-0-0 lx26-amd64 4 4.68 3.9G 3.5G 4.0G 2.9G
job-ID prior name user state submit/start at queue master ja-task-ID
----------------------------------------------------------------------------------------------
6 0.50500 test1.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER
7 0.60500 test4.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER
all.q@comp SLAVE
compute-0-1 lx26-amd64 4 3.26 3.9G 4.2G 4.0G 3.1G
job-ID prior name user state submit/start at queue master ja-task-ID
----------------------------------------------------------------------------------------------
8 0.60500 test2.sh tester r 12/09/2012 14:48:52 all.q@comp MASTER
all.q@comp SLAVE
9 0.60500 test3.sh tester r 12/09/2012 14:48:52 all.q@comp MASTER
all.q@comp SLAVE
compute-0-2 lx26-amd64 4 - 4.1G - 4.0G -
compute-0-3 lx26-amd64 4 0.03 3.9G 2.3G 4.0G 0.0
compute-0-4 lx26-amd64 12 1.02 3.9G 1.5G 4.0G 0.0
job-ID prior name user state submit/start at queue master ja-task-ID
----------------------------------------------------------------------------------------------
10 0.50500 test1.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER

想通过awk处理一个循环,当i=1输出,
compute-0-0 lx26-amd64 4 4.68 3.9G 3.5G 4.0G 2.9G
job-ID prior name user state submit/start at queue master ja-task-ID
----------------------------------------------------------------------------------------------
6 0.50500 test1.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER
7 0.60500 test4.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER
all.q@comp SLAVE
当i=2输出,
compute-0-1 lx26-amd64 4 3.26 3.9G 4.2G 4.0G 3.1G
job-ID prior name user state submit/start at queue master ja-task-ID
----------------------------------------------------------------------------------------------
8 0.60500 test2.sh tester r 12/09/2012 14:48:52 all.q@comp MASTER
all.q@comp SLAVE
9 0.60500 test3.sh tester r 12/09/2012 14:48:52 all.q@comp MASTER
all.q@comp SLAVE
以此类推;

现在我通过shell和awk混合可以做到,
for ((m=1; m<=4; m++)) # m is the number of your compute nodes
do # Get the special node iformation from the cycle
cat qhost.e |sed 1,3d |awk 'BEGIN{node=0} /lx26-/{node+=1} {if(node=="'"$m"'")print}' |awk '
-----中间还要做一些其他处理----
'
done

但是这样混合效率并不高,每次要shell循环一次,awk才提取数据;如果能用awk直接循环效率应该很高

我尝试了下,用cat qhost.e |sed 1,3d |awk 'BEGIN{node=0} /lx26-/{node+=1} {for (i=1; i<=node; i++) {
-----中间还要做一些其他处理----}
}'

但这么处理总出差。

哪位高人能否指点一下,谢谢!
上次由 wuy069 在 2012-12-18 14:33,总共编辑 1 次。
cao627
帖子: 992
注册时间: 2007-12-05 10:57
系统: ubuntu14.04
来自: 金山

Re: 请教关于awk的一个循环问题

#2

帖子 cao627 » 2012-12-15 0:32

代码: 全选

cat qhost.e  | sed 's/compute/#compute/' | awk 'BEGIN{RS="#";FS="\n"}{ if (NR>=2) 相关的处理 }'
 
在特定位置(楼主情况看来是compute)插入特定字符,比如#(这个字符必须原文件中未出现过) ,在awk命令的BEGIN块中设置RS为#,即将 # 和 #之间的内容作为记录,字段分割符油默认的空格设置为换行符 \n.
于是问题简化为对第二条记录开始的每条记录做操作。
假如你有一个三行文本(哪怕再多行),要用ask命令对2,3行(那拍再多行)文本做操作,有必要要用循环吗?
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

Re: 请教关于awk的一个循环问题

#3

帖子 wuy069 » 2012-12-15 8:45

cao627 写了:

代码: 全选

cat qhost.e  | sed 's/compute/#compute/' | awk 'BEGIN{RS="#";FS="\n"}{ if (NR>=2) 相关的处理 }'
 
在特定位置(楼主情况看来是compute)插入特定字符,比如#(这个字符必须原文件中未出现过) ,在awk命令的BEGIN块中设置RS为#,即将 # 和 #之间的内容作为记录,字段分割符油默认的空格设置为换行符 \n.
于是问题简化为对第二条记录开始的每条记录做操作。
假如你有一个三行文本(哪怕再多行),要用ask命令对2,3行(那拍再多行)文本做操作,有必要要用循环吗?
这种方法在我这是存在漏洞的,我的那HOSTNAME并不是只有compute,还有其他的命名;而那ARCH都是lx26-amd64,所以我用“lx26-”做标记,循环输出每一个host的信息(jobid, users, and tasks),这样我再处理每一个host的信息,打印成
---------------------------------------------------------------------------------------------------------
node state load ncpu memtot memuse swapto swapus tasks jobids/users
---------------------------------------------------------------------------------------------------------
compute-0-0 free 4.68* 4 3.9G 3.5G 4.0G 2.9G 3 6/wuy 7/wuy

当i=2时,再打印成
compute-0-1 busy 3.26* 4 3.9G 4.2G* 4.0G 3.1G 4 8/tester 9/tester

以此类推,最后打印成,

----------------------------------------------------------------------------------------------------
node state load ncpu memtot memuse swapto swapus tasks jobids/users
----------------------------------------------------------------------------------------------------
compute-0-0 free 4.68* 4 3.9G 3.5G 4.0G 2.9G 3 6/wuy 7/wuy
compute-0-1 busy 3.26* 4 3.9G 4.2G* 4.0G 3.1G 4 8/tester 9/tester
compute-0-2 down - 4 4.1G - 4.0G - 0
compute-0-3 free 0.03 4 3.9G 2.3G 4.0G 0.0 0
compute-0-4 free 1.02 12 3.9G 1.5G 4.0G 0.0 1 10/wuy
compute-0-5 free 4.68* 4 3.9G 3.5G 4.0G 2.9G 3 11/wuy 12/wuy
compute-0-6 busy 3.26* 4 3.9G 4.2G* 4.0G 3.1G 4 13/tester 14/tester
compute-0-7 free 1.02 12 3.9G 1.5G 4.0G 0.0 1 15/wuy
compute-0-8 free 4.68* 4 3.9G 3.5G 4.0G 2.9G 3 16/wuy 17/eric
compute-0-9 busy 3.26* 4 3.9G 4.2G* 4.0G 3.1G 4 18/tester 19/peter
compute-0-10 free 1.02 12 3.9G 1.5G 4.0G 0.0 1 20/dave
----------------------------------------------------------------------------------------------------
当然这只是一部分,还有命名不为compute的部分
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

Re: 请教关于awk的一个循环问题

#4

帖子 wuy069 » 2012-12-15 8:47

怎么论坛复制粘贴的表都对不齐呢
cao627
帖子: 992
注册时间: 2007-12-05 10:57
系统: ubuntu14.04
来自: 金山

Re: 请教关于awk的一个循环问题

#5

帖子 cao627 » 2012-12-15 11:06

没看懂你的操作要求

像你这种问题应该先概括抽象一下你的要求,将和操作要求无关的内容全剔除掉,然后举个最简单又能涵盖全部要求的例子来说明一下。

我的意思是:比如你要人帮忙求一块树林的面积,只要告诉出它的长和宽,而不必把树林里的每棵树都描述一边。
aerofox
帖子: 1453
注册时间: 2008-05-24 8:30

Re: 请教关于awk的一个循环问题

#6

帖子 aerofox » 2012-12-15 19:28

wuy069 写了:怎么论坛复制粘贴的表都对不齐呢
先回答这个简单的问题,把粘贴的内容放到代码块中就可以了。方法是:选中内容,点标题下面一排按钮中的“Code”
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

Re: 请教关于awk的一个循环问题

#7

帖子 wuy069 » 2012-12-17 16:25

cao627 写了:没看懂你的操作要求

像你这种问题应该先概括抽象一下你的要求,将和操作要求无关的内容全剔除掉,然后举个最简单又能涵盖全部要求的例子来说明一下。

我的意思是:比如你要人帮忙求一块树林的面积,只要告诉出它的长和宽,而不必把树林里的每棵树都描述一边。
前几天忙,把这个事情忘了;好,我重新说一遍我的思路。
有这么一个文件qhost.e,

代码: 全选

HOSTNAME                ARCH         NCPU  LOAD  MEMTOT  MEMUSE  SWAPTO  SWAPUS
 -------------------------------------------------------------------------------
 global                  -               -     -       -       -       -       -
 compute-0-0             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
    job-ID  prior   name       user         state submit/start at     queue      master ja-task-ID
   ----------------------------------------------------------------------------------------------
          6 0.50500 test1.sh   wuy          r     12/09/2012 14:47:26 all.q@comp MASTER
          7 0.60500 test4.sh   wuy          r     12/09/2012 14:47:26 all.q@comp MASTER
                                                                      all.q@comp SLAVE
 compute-0-1             lx26-amd64      4  3.26    3.9G    4.2G    4.0G    3.1G
    job-ID  prior   name       user         state submit/start at     queue      master ja-task-ID
   ----------------------------------------------------------------------------------------------
          8 0.60500 test2.sh   tester       r     12/09/2012 14:48:52 all.q@comp MASTER
                                                                      all.q@comp SLAVE
          9 0.60500 test3.sh   tester       r     12/09/2012 14:48:52 all.q@comp MASTER
                                                                      all.q@comp SLAVE
 compute-0-2             lx26-amd64      4     -    4.1G       -    4.0G       -
 compute-0-3             lx26-amd64      4  0.03    3.9G    2.3G    4.0G     0.0
 compute-0-4             lx26-amd64     12  1.02    3.9G    1.5G    4.0G     0.0
    job-ID  prior   name       user         state submit/start at     queue      master ja-task-ID
    ----------------------------------------------------------------------------------------------
         10 0.50500 test1.sh   wuy          r     12/09/2012 14:47:26 all.q@comp MASTER
 compute-0-5             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
    job-ID  prior   name       user         state submit/start at     queue      master ja-task-ID
    ----------------------------------------------------------------------------------------------
         11 0.50500 test1.sh   wuy          r     12/09/2012 14:47:26 all.q@comp MASTER
         12 0.60500 test4.sh   wuy          r     12/09/2012 14:47:26 all.q@comp MASTER
                                                                      all.q@comp SLAVE
编脚本需要输出以下,

代码: 全选

----------------------------------------------------------------------------------------------------
  node         state    load    ncpu   memtot   memuse   swapto  swapus  tasks  jobids/users
----------------------------------------------------------------------------------------------------
compute-0-0    free     4.68*     4     3.9G     3.5G     4.0G    2.9G     3     6/wuy 7/wuy
compute-0-1    excl     3.26*     4     3.9G     4.2G*    4.0G    3.1G     4     8/tester 9/tester
compute-0-2    down        -      4     4.1G        -     4.0G       -     0                
compute-0-3    free     0.03      4     3.9G     2.3G     4.0G     0.0     0                
compute-0-4    free     1.02     12     3.9G     1.5G     4.0G     0.0     1     10/wuy     
compute-0-5    free     4.68*     4     3.9G     3.5G     4.0G    2.9G     3     11/wuy 12/wuy
----------------------------------------------------------------------------------------------------
解释以下什么意思:
输出的node,load,ncpu,memtot,memuse,swapto,swapus分别对应于qhost.e文件中的HOSTNAME,LOAD,NCPU,MEMTOT,MEMUSE,SWAPTO,SWAPUS.
tasks是节点的总任务数的总使用cpu数,每个任务使用的cpu数为其相应的MASTER数加上SLAVE数;以compute-0-0上的信息为例,此节点有两个任务6和7,它们所使用的cpu数分别为1(1个MASTER)和2(1个MASTER加1个SLAVE)。state是当任务数tasks小于ncpu显示free, 等于ncpu显示excl; 当load为“_"时,state显示down. jobids/users是对应节点任务的job-ID和user.
当load的数字超过tasks的数字为0.5或小于-0.5,在load的数字后面加星"*".
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

Re: 请教关于awk的一个循环问题

#8

帖子 wuy069 » 2012-12-17 16:44

cao627 写了:没看懂你的操作要求

像你这种问题应该先概括抽象一下你的要求,将和操作要求无关的内容全剔除掉,然后举个最简单又能涵盖全部要求的例子来说明一下。

我的意思是:比如你要人帮忙求一块树林的面积,只要告诉出它的长和宽,而不必把树林里的每棵树都描述一边。
按我的第一种思想写脚本,先输出每个节点的信息,
比如i=1输出,
compute-0-0 lx26-amd64 4 4.68 3.9G 3.5G 4.0G 2.9G
job-ID prior name user state submit/start at queue master ja-task-ID
----------------------------------------------------------------------------------------------
6 0.50500 test1.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER
7 0.60500 test4.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER
all.q@comp SLAVE
i=2输出第二个节点的信息,以此类推;

用cat qhost.e |sed 1,3d |$AWK 'BEGIN{node=0} /lx26-/{node+=1} {if(node=="'"$m"'")print}'能分段输出上面的信息,当m=1时输出compute-0-0的信息,以此类推。

这样,当NF==8时,是这一行compute-0-0 lx26-amd64 4 4.68 3.9G 3.5G 4.0G 2.9G
这样可以得到node,ncpu,memtot,memuse,swapto,swapus的信息;
当查找q@这个词,输出的行数就是tasks的数目;而NF>4时,$1为jobid, $4为user.

按照此思想,我写的代码:(这个代码没问题,但是用的是shell的do循环效率不高,想把循环写在awk中)

代码: 全选

#!/bin/sh

# Name: qnod
# Usage: qnod
# Grid Engine resource manager utility script:
# Print a 1-line summary of jobs on each node.
# The printout may be customized as needed.

# Author: [email protected]
# Version: 1.0
# Date: 12 December 2012

# Locations of commands used
QHOST=/opt/gridengine/bin/lx26-amd64/qhost
AWK=/bin/awk

# Heading for printout showing:
# node:         Node hostname
# state:        GE state
# load:         CPU load average
# ncpu:         Number of CPUs
# memtot:       Physical memory
# memuse:       Used physical memory
# swapto:       Total swap
# swapus:       Used swap
# tasks:        Number slots of jobs
# jobids/users: Jobids and corresponding usernames of GE jobs on this node
echo "----------------------------------------------------------------------------------------------------"
echo "  node         state    load    ncpu   memtot   memuse   swapto  swapus  tasks  jobids/users"
echo "----------------------------------------------------------------------------------------------------"
#
# Show the GE node status and parse the results
#
#for m in `seq 1 4`
for ((m=1; m<=11; m++))     # m is the number of your compute nodes
do                         # Get the special node iformation from the cycle
#$QHOST -j |sed 1,3d |$AWK 'BEGIN{node=0} /lx26-/{node+=1} {if(node=="'"$m"'")print}' |$AWK '
cat qhost.e |sed 1,3d |$AWK 'BEGIN{node=0} /lx26-/{node+=1} {if(node=="'"$m"'")print}' |$AWK '
#
# Parse the output of every node information (include jobid, uses, and number jobs per node)
#
  NF==8 { nodename[node]=$1  # 1st line is nodename
          ncpu[node]=$3      # 3rd line is Nprocess CPU of Node
          load[node]=$4      # 4th line is load cpu
          memtot[node]=$5    # 5th line is the total physical memory
          memuse[node]=$6    # 6th line is the used memory
          swapto[node]=$7    # 7th line is the total swap of system
          swapus[node]=$8    # 8th line is the used swap
###############################################################
          getline            # Get the next input line
          njobs[node] = 0    # GE jobs on the node
          ntasks[node] = 0   # Number of tasks started by GE on the node
           }
  /@.+/ {
    if (NF>4) {
         njobs[node]=split($1,b)
         njobs[node]=split($4,c)
     for (i=1; i <= njobs[node]; i++) {
         # Get the list of jobids/users for this node
                jobid[node] = b[1]
                users[node] = c[1]
                 }
         # Append jobid and username to the job list
            jobidlist[node] = jobidlist[node] " " jobid[node] "/" users[node]
             }
         # Get the number tasks of this node
            ntasks[node]=ntasks[node]+1
           if (ntasks[node] < 1) {
              njobs[node] = 0
              ntasks[node] = 0
              jobidlist[node] = ""
               }
              }
END {
# Detemine the node status "down, free or busy"
     if (load[node] == "-")    state[node] = "\033[1;5;37;41mdown\033[0m"
     else if (ntasks[node] < ncpu[node])    state[node] = "\033[1;32;40mfree\033[0m"
     else if (ntasks[node] == ncpu[node])    state[node] = "\033[1;31;40mexcl\033[0m"
# Print out values that we are interested in.  Flag unexpected values with a "*".
     # Flag unexpected CPU load average
        loaddiff = load[node] - ntasks[node]
        if (loaddiff > 0.5 || loaddiff < -0.5) {
                loadflag="*"
        } else
                loadflag=" "
     # High memory usage
        memdiff = memuse[node] - memtot[node]
        if (memdiff >= 0.15) {
               memflag="*"
        } else
                memflag=" "
# Print the summary information on this special node
     if (njobs[node] == 0 && ncpu[node] != 0) {
        #printf ("----------------------------------------------------------------------------------------------------\n")
         printf("%-13s  %5s %8s%s  %4d %8s %8s%s %7s %7s %5s    %-12s\n",
                nodename[node], state[node], load[node], loadflag, ncpu[node], memtot[node],
                memuse[node], memflag, swapto[node], swapus[node], ntasks[node], jobidlist[node])
                 } else {
                     for (i=1; i <= njobs[node]; i++) {
                      #printf ("----------------------------------------------------------------------------------------------------\n")
                       printf("%-13s  %5s %8s%s  %4d %8s %8s%s %7s %7s %5s    %-12s\n",
                              nodename[node], state[node], load[node], loadflag, ncpu[node], memtot[node],
                              memuse[node], memflag, swapto[node], swapus[node], ntasks[node], jobidlist[node])
                               }
                    }
        }'
done
echo "----------------------------------------------------------------------------------------------------"
现在我通过shell和awk混合可以做到,
for ((m=1; m<=4; m++)) # m is the number of your compute nodes
do # Get the special node iformation from the cycle
cat qhost.e |sed 1,3d |awk 'BEGIN{node=0} /lx26-/{node+=1} {if(node=="'"$m"'")print}' |awk '
-----中间还要做一些其他处理----
'
done

但是这样混合效率并不高,每次要shell do循环一次,awk才提取数据;如果能用awk直接循环效率应该很高
上次由 wuy069 在 2012-12-17 17:39,总共编辑 2 次。
头像
bones7456
帖子: 8495
注册时间: 2006-04-12 20:05
来自: 杭州
联系:

Re: 请教关于awk的一个循环问题

#9

帖子 bones7456 » 2012-12-17 16:46

代码: 全选

$ awk '/lx26-/{node++;print node,$0}' /tmp/1 
1  compute-0-0             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
2  compute-0-1             lx26-amd64      4  3.26    3.9G    4.2G    4.0G    3.1G
3  compute-0-2             lx26-amd64      4     -    4.1G       -    4.0G       -
4  compute-0-3             lx26-amd64      4  0.03    3.9G    2.3G    4.0G     0.0
5  compute-0-4             lx26-amd64     12  1.02    3.9G    1.5G    4.0G     0.0
6  compute-0-5             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
拿这个,加上你的“相关的处理”,应该可以搞定了吧?
关注我的blog: ε==3
头像
bones7456
帖子: 8495
注册时间: 2006-04-12 20:05
来自: 杭州
联系:

Re: 请教关于awk的一个循环问题

#10

帖子 bones7456 » 2012-12-17 17:13

几乎全是你自己的代码,没啥差错啊,除了我不知道你为什么要加 getline以外。。。

代码: 全选

$ awk -f /tmp/awk /tmp/1 
compute-0-0    free     4.68*     4     3.9G     3.5G     4.0G    2.9G     3     6/wuy 7/wuy
compute-0-1    excl     3.26*     4     3.9G     4.2G*    4.0G    3.1G     4     6/wuy 7/wuy 8/tester 9/tester
compute-0-2    down        -      4     4.1G        -     4.0G       -     0     6/wuy 7/wuy 8/tester 9/tester
compute-0-3    free     0.03      4     3.9G     2.3G     4.0G     0.0     0     6/wuy 7/wuy 8/tester 9/tester
compute-0-4    free     1.02     12     3.9G     1.5G     4.0G     0.0     1     6/wuy 7/wuy 8/tester 9/tester 10/wuy
compute-0-5    free     4.68*     4     3.9G     3.5G     4.0G    2.9G     3     6/wuy 7/wuy 8/tester 9/tester 10/wuy 11/wuy 12/wuy
$ cat /tmp/awk 
#
# Parse the output of every node information (include jobid, uses, and number jobs per node)
#
  NF==8 { 
	p()
		nodename[node]=$1  # 1st line is nodename
          ncpu[node]=$3      # 3rd line is Nprocess CPU of Node
          load[node]=$4      # 4th line is load cpu
          memtot[node]=$5    # 5th line is the total physical memory
          memuse[node]=$6    # 6th line is the used memory
          swapto[node]=$7    # 7th line is the total swap of system
          swapus[node]=$8    # 8th line is the used swap
###############################################################
#          getline            # Get the next input line  这是为什么???
          njobs[node] = 0    # GE jobs on the node
          ntasks[node] = 0   # Number of tasks started by GE on the node
           }
  /@.+/ {
    if (NF>4) {
         njobs[node]=split($1,b)
         njobs[node]=split($4,c)
     for (i=1; i <= njobs[node]; i++) {
         # Get the list of jobids/users for this node
                jobid[node] = b[1]
                users[node] = c[1]
                 }
         # Append jobid and username to the job list
            jobidlist[node] = jobidlist[node] " " jobid[node] "/" users[node]
             }
         # Get the number tasks of this node
            ntasks[node]=ntasks[node]+1
           if (ntasks[node] < 1) {
              njobs[node] = 0
              ntasks[node] = 0
              jobidlist[node] = ""
               }
              }
function p() {
# Detemine the node status "down, free or busy"
     if (load[node] == "-")    state[node] = "\033[1;5;37;41mdown\033[0m"
     else if (ntasks[node] < ncpu[node])    state[node] = "\033[1;32;40mfree\033[0m"
     else if (ntasks[node] == ncpu[node])    state[node] = "\033[1;31;40mexcl\033[0m"
# Print out values that we are interested in.  Flag unexpected values with a "*".
     # Flag unexpected CPU load average
        loaddiff = load[node] - ntasks[node]
        if (loaddiff > 0.5 || loaddiff < -0.5) {
                loadflag="*"
        } else
                loadflag=" "
     # High memory usage
        memdiff = memuse[node] - memtot[node]
        if (memdiff >= 0.15) {
               memflag="*"
        } else
                memflag=" "
# Print the summary information on this special node
     if (njobs[node] == 0 && ncpu[node] != 0) {
        #printf ("----------------------------------------------------------------------------------------------------\n")
         printf("%-13s  %5s %8s%s  %4d %8s %8s%s %7s %7s %5s    %-12s\n",
                nodename[node], state[node], load[node], loadflag, ncpu[node], memtot[node],
                memuse[node], memflag, swapto[node], swapus[node], ntasks[node], jobidlist[node])
                 } else {
                     for (i=1; i <= njobs[node]; i++) {
                      #printf ("----------------------------------------------------------------------------------------------------\n")
                       printf("%-13s  %5s %8s%s  %4d %8s %8s%s %7s %7s %5s    %-12s\n",
                              nodename[node], state[node], load[node], loadflag, ncpu[node], memtot[node],
                              memuse[node], memflag, swapto[node], swapus[node], ntasks[node], jobidlist[node])
                               }
                    }
        }
END{p()}
关注我的blog: ε==3
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

Re: 请教关于awk的一个循环问题

#11

帖子 wuy069 » 2012-12-17 17:24

cao627 写了:没看懂你的操作要求

像你这种问题应该先概括抽象一下你的要求,将和操作要求无关的内容全剔除掉,然后举个最简单又能涵盖全部要求的例子来说明一下。

我的意思是:比如你要人帮忙求一块树林的面积,只要告诉出它的长和宽,而不必把树林里的每棵树都描述一边。
第二种思想:
先看qhost.e文件的前面几行,
compute-0-0 lx26-amd64 4 4.68 3.9G 3.5G 4.0G 2.9G
job-ID prior name user state submit/start at queue master ja-task-ID
----------------------------------------------------------------------------------------------
6 0.50500 test1.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER
7 0.60500 test4.sh wuy r 12/09/2012 14:47:26 all.q@comp MASTER
all.q@comp SLAVE
compute-0-1 lx26-amd64 4 3.26 3.9G 4.2G 4.0G 3.1G
job-ID prior name user state submit/start at queue master ja-task-ID
----------------------------------------------------------------------------------------------
8 0.60500 test2.sh tester r 12/09/2012 14:48:52 all.q@comp MASTER
all.q@comp SLAVE
9 0.60500 test3.sh tester r 12/09/2012 14:48:52 all.q@comp MASTER
all.q@comp SLAVE

从节点的信息来看,NF分别为8,10,9,2..,然后又到节点compute-0-的NF==8,这样可以用NF==8,然后用while做循环,

可惜最后没整成功,

代码: 全选

#!/bin/sh

# Name: qnod
# Usage: qnod
# Grid Engine resource manager utility script:
# Print a 1-line summary of jobs on each node.
# The printout may be customized as needed.

# Author: [email protected]
# Version: 1.0
# Date: 12 December 2012

# Locations of commands used
QHOST=/opt/gridengine/bin/lx26-amd64/qhost
AWK=/bin/awk

# Heading for printout showing:
# node:         Node hostname
# state:        GE state
# load:         CPU load average
# ncpu:         Number of CPUs
# memtot:       Physical memory
# memuse:       Used physical memory
# swapto:       Total swap
# swapus:       Used swap
# tasks:        Number slots of jobs
# jobids/users: Jobids and corresponding usernames of GE jobs on this node
echo "----------------------------------------------------------------------------------------------------"
echo "  node         state    load    ncpu   memtot   memuse   swapto  swapus  tasks  jobids/users"
echo "----------------------------------------------------------------------------------------------------"
#
# Show the GE node status and parse the results
#
#$QHOST -j |sed 1,3d |$AWK 'BEGIN{node=0}
cat qhost.e |sed 1,3d |$AWK '
#
# Parse the output of every node information (include jobid, uses, and number jobs per node)
#
  NF==8 { nodename[node]=$1  # 1st line is nodename
          ncpu[node]=$3      # 3rd line is Nprocess CPU of Node
          load[node]=$4      # 4th line is load cpu
          memtot[node]=$5    # 5th line is the total physical memory
          memuse[node]=$6    # 6th line is the used memory
          swapto[node]=$7    # 7th line is the total swap of system
          swapus[node]=$8    # 8th line is the used swap
###############################################################
          getline            # Get the next input line
          njobs[node] = 0    # GE jobs on the node
          nmaster[node] = 0  # Number of tasks started by GE on the node
          nslave[node] = 0
          listnode=0                       # Set to > 0 if this node gets flagged
    while (NF >= 2) {
      if ($9=="MASTER") {
       for (i=1; i <= njobs[node]; i++) {
         # Get the list of jobids/users for this node
                jobid[node] = $1
                users[node] = $4
         # Append jobid and username to the job list
            jobidlist[node] = jobidlist[node] " " jobid[node] "/" users[node]
            }
         # Get the number MASTER of this node
            nmaster[node]=nmaster[node]+1
             }
      if ($2=="SLAVE") {
         nslave[node]=nslave[node]+1
          }
      {ntasks[node]=nmaster[node]+nslave[node]}
               getline                  # Get the next input line
       }
#
# Detemine the node status "down, free or busy"
     if (load[node] == "-")    state[node] = "\033[1;5;37;41mdown\033[0m"
     else if (ntasks[node] < ncpu[node])    state[node] = "\033[1;32;40mfree\033[0m"
     else if (ntasks[node] == ncpu[node])    state[node] = "\033[1;31;40mbusy\033[0m"
# Print out values that we are interested in.  Flag unexpected values with a "*".
     # Flag unexpected CPU load average
        loaddiff = load[node] - ntasks[node]
        if (loaddiff > 0.5 || loaddiff < -0.5) {
                loadflag="*"
                listnode++
        } else
                loadflag=" "
     # High memory usage
        memdiff = memuse[node] - memtot[node]
        if (memdiff >= 0.15) {
               memflag="*"
               listnode++
        } else
                memflag=" "

        # CONFIGURE: Comment out the line below
        # Omit down nodes from the flagged list because we do not bother to see them
        # (Use "pbsnodes -l" to list down nodes).
        if (state[node] == "down") listnode=0

# Print the summary information on this special node
if (!listflagged || listnode > 0)
        #printf ("----------------------------------------------------------------------------------------------------\n")
         printf("%-13s  %5s %8s%s  %4d %8s %8s%s %7s %7s %5s    %-12s\n",
                nodename[node], state[node], load[node], loadflag, ncpu[node], memtot[node],
                memuse[node], memflag, swapto[node], swapus[node], ntasks[node], jobidlist[node])
}'

echo "----------------------------------------------------------------------------------------------------"
最后tasks和jobidlist输出有问题,应该是最后用END才是正确的tasks和jobidlist,但用END,又包不进while里面。
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

Re: 请教关于awk的一个循环问题

#12

帖子 wuy069 » 2012-12-17 17:33

bones7456 写了:几乎全是你自己的代码,没啥差错啊,除了我不知道你为什么要加 getline以外。。。
我没有说我的这个代码有问题;我是说我用shell的do循环,效率不高;我是想把那循环直接做在awk中,但我试了多次,在awk中加入这种循环没成功。

awk是一行一行的处理;我处理了上面的行,下面需要用到变量,就用了呗;当然也可以写在BEGIN里。
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

Re: 请教关于awk的一个循环问题

#13

帖子 wuy069 » 2012-12-17 17:35

bones7456 写了:

代码: 全选

$ awk '/lx26-/{node++;print node,$0}' /tmp/1 
1  compute-0-0             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
2  compute-0-1             lx26-amd64      4  3.26    3.9G    4.2G    4.0G    3.1G
3  compute-0-2             lx26-amd64      4     -    4.1G       -    4.0G       -
4  compute-0-3             lx26-amd64      4  0.03    3.9G    2.3G    4.0G     0.0
5  compute-0-4             lx26-amd64     12  1.02    3.9G    1.5G    4.0G     0.0
6  compute-0-5             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
拿这个,加上你的“相关的处理”,应该可以搞定了吧?
你这个明显不行;

我是要做awk的循环,每次是输出节点和任务的信息;你这个只是输出了节点,相应的节点任务并没有输出
头像
bones7456
帖子: 8495
注册时间: 2006-04-12 20:05
来自: 杭州
联系:

Re: 请教关于awk的一个循环问题

#14

帖子 bones7456 » 2012-12-18 9:48

wuy069 写了:
bones7456 写了:

代码: 全选

$ awk '/lx26-/{node++;print node,$0}' /tmp/1 
1  compute-0-0             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
2  compute-0-1             lx26-amd64      4  3.26    3.9G    4.2G    4.0G    3.1G
3  compute-0-2             lx26-amd64      4     -    4.1G       -    4.0G       -
4  compute-0-3             lx26-amd64      4  0.03    3.9G    2.3G    4.0G     0.0
5  compute-0-4             lx26-amd64     12  1.02    3.9G    1.5G    4.0G     0.0
6  compute-0-5             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
拿这个,加上你的“相关的处理”,应该可以搞定了吧?
你这个明显不行;

我是要做awk的循环,每次是输出节点和任务的信息;你这个只是输出了节点,相应的节点任务并没有输出
你看我10楼的。
关注我的blog: ε==3
头像
wuy069
帖子: 91
注册时间: 2011-05-02 11:00

Re: 请教关于awk的一个循环问题

#15

帖子 wuy069 » 2012-12-18 10:24

bones7456 写了:
wuy069 写了:
bones7456 写了:

代码: 全选

$ awk '/lx26-/{node++;print node,$0}' /tmp/1 
1  compute-0-0             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
2  compute-0-1             lx26-amd64      4  3.26    3.9G    4.2G    4.0G    3.1G
3  compute-0-2             lx26-amd64      4     -    4.1G       -    4.0G       -
4  compute-0-3             lx26-amd64      4  0.03    3.9G    2.3G    4.0G     0.0
5  compute-0-4             lx26-amd64     12  1.02    3.9G    1.5G    4.0G     0.0
6  compute-0-5             lx26-amd64      4  4.68    3.9G    3.5G    4.0G    2.9G
拿这个,加上你的“相关的处理”,应该可以搞定了吧?
你这个明显不行;

我是要做awk的循环,每次是输出节点和任务的信息;你这个只是输出了节点,相应的节点任务并没有输出
你看我10楼的。
10楼怎么呢;你给我最后输出的jobidlist全错了啊
回复