如何搜索文件的某些部分,然后仅提取该部分中的相关信息?

如何搜索文件的某些部分,然后仅提取该部分中的相关信息?

我有一个文本文件,它是一个服务器报告,其中包含大约 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 来执行非性能关键的系统工具和任务,知道如何阅读这些工具和任务总有一天会得到回报。

能够搜索、剖析线条和抓取信息,并以灵活、强大的数据结构组织结果,将在这种情况下以及随后的许多类似情况中节省工作量。

相关内容