从文件中 Grep 最后一个匹配项

从文件中 Grep 最后一个匹配项

我正在对日志文件运行以下命令,只想获取最后一个/最新的匹配项。有时可能只有一个匹配项,有时可能有多个匹配项,这给我带来了问题,因为以下命令会返回两个匹配项:

cat "$(ls -t | head -n1)" | grep -P "(NODE1[\s\S]*TEST\s=\sPOWER[\s\S]*OUTPUT\s=\s\d+?.*\s+;?)"

>>>>> (results in)...

NODE1 2018-03-06 12:01:23
  TEST = POWER
  EVENT_TIME = 2018-03-06 12:01:23
  OUTPUT = 12

;

NODE1 2018-03-06 12:03:23
  TEST = POWER
  EVENT_TIME = 2018-03-06 12:03:23
  OUTPUT = 7

;

如果有多个匹配组,我需要最后一个匹配组。这可以用 grep/regex 实现吗?还是我需要将结果导入 sed/awk?如果可以,怎么做?

答案1

我向你提出这个解决方案:

cat <your_source_file> | sed -n '/NODE1/,/;/p' | tr '\n' '|' | awk -F ';' '{print $(NF-1)}'|tr '|' '\n'

sed -n '/NODE1/,/;/p'- 找到‘NODE1’块。

tr '\n' '|'将换行符转换为记录分隔符,因此表列将以“;”分隔。

awk -F ';' '{print $(NF-1)}'- 打印表格的最后一列。

tr '|' '\n'- 返回上一个视图进行记录。

awk -F ';' '{for(i=(NF-1); i>0; i--){ if($i ~ "TEST = POWER"){print $i} } }'- 仅限“TEST = POWER”事件。

答案2

根据 Yurij 的建议,我开始研究使用tac而不是 cat,并撤销我的grep陈述。现在,我从下往上查看文件并抓取第一个匹配项:

tac "$(ls -t | head -n1)" | grep -m 1 -P "\d+[\s\S]*TEST\s=\sTXPOWER" | tac

答案3

我发现perl这样更方便:

perl -lane 'if(/^NODE1 /&&($#n=-1)../^;$/){push @n,$_} END{print $_ for @n}' file

解释:

perl实用的提取和报告语言。
-lane通常对单行有用的开关。
'实际程序指令的开始
if(/^NODE1 /&&($#n=-1)../^;$/)仅考虑以 stat 开头的行开头、NODE1后跟空格、以包含单个分号的行结尾的文本部分。
•在文本部分的开头/^NODE1 /&&($#n=-1)重置数组。 •将文本部分中的每一行保存为名为 的数组的元素 •当整个文件都被解析后,打印保存在 中的文本部分。 •程序指令的结束。 •这是您要处理的文件的名称的占位符。@n
{push @n,$_}@n
END{print $_ for @n}@n
'
file

相关内容