正如标题所示,我将数据存储在多个平面文件中,格式如下:
215,,,215,16.4,0,2011/05/11 00:00:06
215,,,215,16.3,0,2011/05/11 00:00:23
217,,,217,16.3,0,2011/05/11 00:00:11
213,,,213,16.3,0,2011/05/11 00:00:17
215,,,215,16.3,0,2011/05/11 00:00:30
我目前正在使用以下awk命令:
awk -F ',' '{gsub(/[\/:]/," ",$7); print mktime($7)":"$1":"$5}' MyFile
这给我输出如下(日期转换为纪元,冒号分隔符并稍微移动一下):
1305068406:215:16.4
1305068430:215:16.3
1305068411:217:16.3
1305068417:213:16.3
1305068423:215:16.3
由于写入文件时出现一些打嗝,输入文件可能不是按日期顺序排列,所以接下来我将上面awk命令的输出输出到sort -n
,这将确保数据按数字排序最顶层的纪元时间。
1305068406:215:16.4
1305068411:217:16.3
1305068417:213:16.3
1305068423:215:16.3
1305068430:215:16.3
然后我将已排序的输出传递给另一个awk命令:
awk -F ':' 'BEGIN {ORS=" ";c="rrdtool update ccdata2.rrd"; print c} NR % 100 == 0 {print "&& "c} $1>p {print $0;p=$0}'
这将生成以下输出,并确保若干规则:
&&
和一个新的rrdtool update ccdata.rrd
前缀(似乎rrdtool喜欢带有大量记录的更新)最终输出如下:
rrdtool update ccdata2.rrd 1305068406:215:16.4 1305068411:217:16.3 1305068417:213:16.3 1305068423:215:16.3 1305068430:215:16.3
如果有300条记录(你明白了)
rrdtool update ccdata2.rrd x:x:x <100 times> && rrdtool update ccdata2.rrd x:x:x <another 100 times>
然后我将命令的输出传递给bash
,以便shell执行输出rrdtool update
命令。
完整命令是:
awk -F ',' '{gsub(/[\/:]/," ",$7); print mktime($7)":"$1":"$5}' MyFile | sort -n | awk -F ':' 'BEGIN {ORS=" ";c="rrdtool update ccdata2.rrd"; print c} NR % 100 == 0 {print "&& "c} $1>p {print $0;p=$0}' | bash
如何改进上述流程?你会如何实现同样的目标?请在答案中说明原因。 (即两个awk命令可以转换为一个)
答案 0 :(得分:2)
由于数据只包含[0-9:。]和换行符,xargs
应该可以安全使用(一次),所以你可以丢失第二个awk并执行:
awk -F ',' '{gsub(/[\/:]/," ",$7); print mktime($7)":"$1":"$5}' MyFile |
sort -n |
xargs rddtool update ccdata2.rrd
xargs会尽可能多地将参数压缩到rddtool命令,如果参数的数量超过ARG_MAX,它将运行更多命令,直到所有输入都被处理完毕。
修改强>
如果纪元日期大于最后一个日期,要具有仅打印出一行的功能,我已将awk命令更新为以下内容:
awk -F ',' '{gsub(/[\/:]/," ",$7)} $7>p {print mktime($7)":"$1":"$5;p=$7}' MyFile |
sort -n |
xargs rddtool update ccdata2.rrd