[英]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.