如何运行程序并使用KornShell解析输出

时间:2013-02-25 17:39:19

标签: shell unix scripting ksh

我对KornShell(ksh)很新。我有一个需要用ksh完成的项目。问题是:

  

请写一个将运行'bonnie'基准的ksh脚本   实用程序并解析输出以获取块写入,块的值   阅读和随机搜索/ s。还要考虑如何使用这些值   与之前测试的结果进行比较。为了...的目的   这个测试,请限制自己使用标准GNU实用程序(sed,awk,   grep,cut等)。

     

以下是'bonnie'实用程序的输出:

# bonnie -s 50M -d /tmp        
File '/tmp/Bonnie.2001096837', size: 52428800
Writing with putc()...done
Rewriting...done
Writing intelligently...done
Reading with getc()...done
Reading intelligently...done
Seeker 1.S.e.eker 2.S.e.eker 3...start 'em...done...done...done...
              -------Sequential Output-------- ---Sequential Input-- --Random--
              -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
Machine    MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec  %CPU /sec  %CPU
         50.0 36112 34.1 138026  1.9 179048  7.0 51361 51.1 312242  4.3 15211.4 10.3 

任何关于如何编写此脚本的建议都会非常感激。

感谢阅读!

2 个答案:

答案 0 :(得分:0)

这是一个简单的实验解决方案,假设最后一行始终包含您想要的数据:

 #              -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
 # Machine    MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec  %CPU /sec  %CPU
 #            50.0 36112 34.1 138026  1.9 179048  7.0 51361 51.1 312242  4.3 15211.4 10.3 
 #                block write, block read and random seeks/s
 bonnie++ \
 | awk '
       {line=$0} 
        END{
          # print "#dbg:last_line=" $line
          split(line, lineArr)
          printf ("blkWrt=%s\tblkRd=%s\tRandSks=%s\n", lineArr[4], lineArr[8], lineArr[12])
        }' # > bonnieOutput
  # ------^^ remove # to write output to file

(请注意,bonnie ++之后的\字符必须是该行的最后一个字符,不允许空格或TABS !!!(否则会爆炸!);-))

Awk读取通过管道传递的所有输入行。当您在awk的END {}块中时,将最后一行读入lineArr [],然后使用数据中字段的索引号将该行中所需的元素打印出来,这样lineArr[4]将返回最后一行数据中的第4个字段lineArr[12],第12行等。您可能需要调整用于获取要显示的数据的索引号。 (你必须弄明白!;-)

要将数据保存到文件,请通过取消注释(删除#}'之间的> bonnieOutput字符来使用shell重定向。将#字符保留到位你得到了你需要的输出,然后你可以将它重定向到一个文件。

毋庸置疑,我在printf中使用的标签blkWrt=主要用于调试。一旦你确定需要捕获哪些数据,并且每次都可以在同一位置可靠地出现这些数据,那么你可以删除这些标签,然后你就可以得到一个可以处理其他程序的干净数据文件。

请记住,几乎所有Unix工具箱实用程序都是面向行的,即他们希望一次处理1行数据,并且通常会有技巧来查看正在处理的内容。注意我在END {}块顶部包含的#dbg行。您必须删除“#”才能取消注释以查看调试输出。

除了可以做的事情还有很多,但是如果你想用awk学习ksh / unix工具箱,你将不得不花时间了解这些功能是什么。如果您已经阅读了包含您正在使用的问题的章节,并且不了解如何开始解决此问题,那么您最好再次阅读本章,好吗? ;-)

修改

请注意,在awk中,变量$0包含当前行中的所有文本(由RS变量值定义,通常是Unix行结束字符{{1} })。其他编号值,即\n$1,表示当前行($2)上的第一个或第二个“字段”。

根据我对您的新评论,您希望从包含文本“Latency”的行中提取值。这更容易处理。基本模式将是

$0

所以这段代码说,通过管道读取bonnie ++的所有输出到awk,当你找到包含文本“Latency”的行时,使用printf打印在第4,第8和第12个字段中找到的值包含自我描述标签的格式字符串,如blkWrt等。 您必须更改$ 4等,以正确匹配每个数据元素的当前行中的数字。 I.E.也许是5美元,9美元,13美元,3美元,9美元,24美元?好?

请注意/ Latency /区分大小写,如果输出中有其他位置出现,那么我们将不得不修改用于过滤输出的reg-exp“规则”。

作为一个学习练习,作为任何Unix人每天使用的非常基本的工具,跳过awk,看看 bonnie++ \ | awk ' /Latency/{ # print "#dbg:latency_line=" $0 printf ("blkWrt=%s\tblkRd=%s\tRandSks=%s\n", $4, $8, $12) }' # > bonnieOutput 给你的是什么。

IHTH

答案 1 :(得分:0)

在Shellter的帮助下得到了答案!

bonnie++\

| awk'/ Machine / {f = 1; next} f {

   print "#dbg: line_needed=" $0
   printf("blkWrt=%s\t blkRd=%s\t RandSks=%s\n", $4, $8, $12);exit

}“