我正在尝试解析Salt的高状态输出,这已经被证明是很困难的。没有将输出更改为json
,因为我仍然希望它是人类可读的。
将摘要转换成机器可读的东西的最佳方法是什么?
Summary for app1.domain.com
--------------
Succeeded: 278 (unchanged=12, changed=6)
Failed: 0
--------------
Total states run: 278
Total run time: 7.383 s
--
Summary for app2.domain.com
--------------
Succeeded: 278 (unchanged=12, changed=6)
Failed: 0
--------------
Total states run: 278
Total run time: 7.448 s
--
Summary for app0.domain.com
--------------
Succeeded: 293 (unchanged=13, changed=6)
Failed: 0
--------------
Total states run: 293
Total run time: 7.510 s
没有更好的主意,我尝试grep和awk的输出,并插入到一个csv。
这两个工作:
cat ${_FILE} | grep Summary | awk '{ print $3} ' | \
tr '\n' ',' | sed '$s/,$/\n/' >> /tmp/highstate.csv;
cat ${_FILE} | grep -oP '(?<=unchanged=)[0-9]+' | \
tr '\n' ',' | sed '$s/,$/\n/' >> /tmp/highstate.csv;
但是这个失败了,但是在Reger中可以工作
cat ${_FILE} | grep -oP '(?<=\schanged=)[0-9]+' | \
tr '\n' ',' | sed '$s/,$/\n/' >> /tmp/highstate.csv;
EDIT 1:@vintnes @ikegami我同意我更愿意使用json输出解析输出,但是Salt在输出到josn时没有提供更改摘要。到目前为止,这是我所拥有的,虽然非常丑陋,但它正在工作。
cat ${_FILE} | grep Summary | awk '{ print $3} ' | \
tr '\n' ',' | sed '$s/,$/\n/' >> /tmp/highstate_tmp.csv;
cat ${_FILE} | grep -oP '(?<=unchanged=)[0-9]+' | \
tr '\n' ',' | sed '$s/,$/\n/' >> /tmp/highstate_tmp.csv;
cat ${_FILE} | grep unchanged | awk -F' ' '{ print $4}' | \
grep -oP '(?<=changed=)[0-9]+' | tr '\n' ',' | sed '$s/,$/\n/' >> /tmp/highstate_tmp.csv;
cat ${_FILE} | { grep "Warning" || true; } | awk -F: '{print $2+0} END { if (!NR) print "null" }' | \
tr '\n' ',' | sed '$s/,$/\n/' >> /tmp/highstate_tmp.csv;
cat ${_FILE} | { grep "Failed" || true; } | awk -F: '{print $2+0} END { if (!NR) print "null" }' | \
tr '\n' ',' | sed '$s/,$/\n/' >> /tmp/highstate_tmp.csv;
csvtool transpose /tmp/highstate_tmp.csv > /tmp/highstate.csv;
sed -i '1 i\instance,unchanged,changed,warning,failed' /tmp/highstate.csv;
输出:
instance,unchanged,changed,warning,failed
app1.domain.com,12,6,,0
app0.domain.com,13,6,,0
app2.domain.com,12,6,,0
3条答案
按热度按时间qlzsbp2j1#
开始。如果输出包含警告,此操作也会起作用。请注意,输出的顺序与您指定的顺序不同;它是每个记录在文件中出现的顺序。任何问题都不要犹豫。
split($3 $4 $5, S, /[^0-9]+/)
通过忽略前两个“单词”Succeeded: ###
并使用任意数量的非数字作为分隔符来处理警告的可能性。/^Fail/
上打印,而不是使用/^Summ/
和END
。u59ebvdq2#
通过STDIN提供输入,或提供要作为参数读取的文件的路径。
简明版本:
t2a7ltrp3#
改进@vintnes的答案。生成制表符分隔的CSV输出
编写awk脚本,按顺序从行中读取值。在读取时打印每个记录。
脚本.awk
运行脚本
制表符分隔的CSV输出
逗号分隔CSV输出
输出
解释
BEGIN {print("computer","succeeded","unchanged","changed","failed","states run","run time");}
打印标题CSV行
FNR%8 == 1 {arr[1] = $3}
从中的第3个字段提取arr[1]值(8行中的第1行)
FNR%8 == 3 {arr[2] = $2; arr[3] = extractNum($3); arr[4] = extractNum($4)}
从中的第2、3、4个字段提取arr[2,3,4]值(8行中的第3行)
FNR%8 == 4 {arr[5] = $2;}
从中的第2个字段提取arr[5]值(8行中的第4行)
FNR%8 == 6 {arr[6] = $4;}
从中的第4个字段提取arr[6]值(8行中的第6行)
FNR%8 == 7 {arr[7] = $4;
从中的第4个字段提取arr[7]值(8行中的第7行)
print arr[1],arr[2],arr[3],arr[4],arr[5],arr[6],arr[7];}
在读取完8行中的第7行时打印提取变量的数组元素。
function extractNum(str){match(str,/[[:digit:]]+/,m);return m[0];}
从文本字段中提取数字的实用程序函数。