繁体   English   中英

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

[英]How to run a program and parse the output using KornShell

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

请编写一个ksh脚本,该脚本将运行“ bonnie”基准实用程序并解析输出以获取用于块写入,块读取和随机查找/秒的值。 还请考虑如何使用这些值与以前的测试结果进行比较。 出于测试目的,请限制于标准的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 

关于如何编写此脚本的任何建议将不胜感激。

谢谢阅读!

这是一个简单的解决方案,假设最后一行将始终包含所需的数据:

 #              -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 ++之后的\\ char必须是该行的最后一个字符,不允许有空格或制表符!!!!!!(-))

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

将数据保存到一个文件,通过取消注释(除去使用shell重定向#之间的字符}'> bonnieOutput 。保留#字符到位,直到你得到你所需要的输出,那么你可以把它重定向到一个文件中。

不用说,我在printf使用的标签(如blkWrt=主要用于调试。 一旦确定了需要捕获的数据,并且每次都可靠地将其显示在相同的位置,便可以删除这些标签,然后获得一个可以与其他程序一起处理的漂亮的数据文件。

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

还有很多事情要做,但是如果您想使用awk学习ksh / unix工具箱,则必须花时间了解这些功能。 如果您已经阅读了包含您正在处理的问题的一章,并且甚至不了解如何开始解决该问题,那么也许您最好再次阅读该章,好吗? ;-)

编辑

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

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

 bonnie++ \
 | awk '
       /Latency/{ 
          # print "#dbg:latency_line=" $0
          printf ("blkWrt=%s\tblkRd=%s\tRandSks=%s\n", $4, $8, $12)
        }' # > bonnieOutput

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

请注意,/ Latency /区分大小写,并且如果输出中的单词出现在其他地方,那么我们将不得不修改用于过滤输出的reg-exp“ rule”。

作为学习练习和所有Unix用户每天都使用的非常基本的工具,请跳过awk,然后看看bonnie++| grep 'Latency'是什么bonnie++| grep 'Latency' bonnie++| grep 'Latency'可以帮助您。

高温超导

刚从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

}'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM