我有一个文本文件,它是一个服务器报告,其中包含大约 1000 行信息。我正在尝试编写一个脚本,可以在报告中搜索我正在寻找的某些信息。
例如:
服务器1健康检查
日期 - 错误计数
2015年6月25日:14
2015 年 6 月 24 日: 21
2015 年 6 月 23 日: 17 号
2015 年 6 月 24 日: 33
服务器2健康检查
日期 - 错误计数
2015年6月25日:4
2015 年 6 月 24 日: 13
2015 年 6 月 23 日: 21
2015 年 6 月 24 日: 33
X引起的错误
服务器1:
32
服务器2:
24
这三个部分是
- “服务器健康检查1”,
- “服务器运行状况检查 2”,以及
- “由 x 引起的错误。”
我需要提取的每个部分的数据都以粗体显示。
有谁知道我该怎么做?
我知道我可以使用,grep
但不能grep
与-A
、-B
和-C
标志一起使用。
答案1
怎么样sed带有 gotos(震惊、恐怖)的脚本。如果您更准确地描述数据,这可以简化。
sed -n '
:start
/Server .* Health Check/{
n
/Date - Count/n
:loop1
/ : /{p; n; b loop1
}
b start
}
/Errors caused by/{
n
:loop2
/Server/n
/^[0-9]/{p; n; b loop2
}
b start
}
'
该脚本识别标题的第一种样式,并输入 {} 部分。它读取下一行 (n),如果它是日期标头,则读取另一行。如果该行与“ : ”样式行 (/ : /) 匹配,则会进入 {} 部分,打印该行 (p),读取下一行 (n),并分支 (b) 到标签 Loop1。当没有更多的行匹配时,它会分支到标签开始。
当看到第二种样式的标题时,也会发生同样的事情。
答案2
好吧,如果你有 GNU 工具,你可以这样做:
for match in \
Server\ Health\ Check\ 1
Server\ Health\ Check\ 2
Errors\ caused\ by\ X
do grep -Fxm1 "$match"
case $match in
(S*) sed -nEu '/^[0-9/:]+/!q;p';;
(*) sed -u '4q;3d;1d';;
esac;done <file
这里的假设是有一些在您感兴趣的部分之间插入数据(因为否则cat
:)。
没有 GNU 工具:
grep -nxE 'Server Health Check [12]|Errors caused by X' <file |
sed 's|\([^:]*\):S.*|\1,/\n.*[^0-9/:]/{\1!P?}?|
s|\([^:]*\):E.*|\1{N;s/.*\\n//p;N;s///p?}?|
y/?/\n/' | sed -e1!N -f- -eD ./file
答案3
根据您最熟悉的语言使用完整的脚本语言,例如 Perl、Python 或 Ruby。如果没有,学习 Python 可能会给你带来最大的收益。许多 Linux 发行版使用 Python 来执行非性能关键的系统工具和任务,知道如何阅读这些工具和任务总有一天会得到回报。
能够搜索、剖析线条和抓取信息,并以灵活、强大的数据结构组织结果,将在这种情况下以及随后的许多类似情况中节省工作量。