awk找到最后一个匹配并打印下N行

时间:2014-09-09 06:45:51

标签: regex bash awk

我有一个包含以下内容的日志文件:

Date: 2014-09-07
Price: 1.35
Amount: 20
ProcessedBy: Bill

Some other contents

Date: 2014-09-08
Price: 10.1
Amount: 15
ProcessedBy: Alice

Some other contents

Date: 2014-09-09
Price: 100
Amount: 2.6
ProcessedBy: Boss

Some other contents

我想使用awk查找最后一个“日期”,并打印以下三行。

Date: 2014-09-09
Price: 100
Amount: 2.6
ProcessedBy: Boss

我使用代码:

awk '/Date/ {x=NR}; END{NR>=x && NR<=x+3} LOG_FILE

然而,似乎我不能在END之后放置NR输出。

如何在最后一场比赛后获得以下N行?

感谢您的关注!

5 个答案:

答案 0 :(得分:2)

$ awk  '/^Date:/ {c=1; a=$0;next} c<=3{c=c+1;a=a"\n"$0}END{print a}' LOG_FILE
Date: 2014-09-09
Price: 100
Amount: 2.6
ProcessedBy: Boss

一次取代码:

  • /^Date:/ {c=1; a=$0;next}

    每次遇到以Date:开头的行时,请将计数器c分配给一个,将该行指定给变量a,然后跳到下一行

  • c<=3{c=c+1;a=a"\n"$0}

    如果计数器小于或等于3,则递增计数器并将新行保存到变量a的末尾。

  • END{print a}

    打印最后看到的a

此问题的第二个版本的代码

$ awk -v RS=  '/^Date:/ {a=$0} END{print a}' LOG_FILE
Date: 2014-09-09
Price: 100
Amount: 2.6
ProcessedBy: Boss

一次取代码:

  • -v RS=

    awk将其输入划分为“记录”。这可以通过将记录分隔符RS设置为空行来实现。 (对于GNU awk,空的RS匹配空行。对于其他版本的awk,您可能需要做一些不同的事情。)

  • /^Date:/ {a=$0}

    每次遇到以Date:开头的记录时,都会保存在变量a中。

  • END{print a}

    在运行结束时,会打印最后看到的a值。

此问题第一版的代码

$ awk -v RS=  'END{print $0}' LOG_FILE
Date: 2014-09-09
Price: 100
Amount: 2.6
ProcessedBy: Boss

答案 1 :(得分:1)

你也可以尝试perl,

$ perl -0777pe 's/.*?\n(Date:(?:(?!Date:).)*)$/\1/s' file
Date: 2014-09-09
Price: 100
Amount: 2.6
ProcessedBy: Boss

答案 2 :(得分:1)

你可以使用这个awk:

awk -v RS= '/^Date:/{data=$0} END{print data}' file
Date: 2014-09-09
Price: 100
Amount: 2.6
ProcessedBy: Boss

答案 3 :(得分:0)

您可以尝试在两个模式之间打印行,如下所示

awk '/StartPattern/,/EndPattern/' FileName 

对你来说它可以像这样工作

awk '/2014-09-09/,/ProcessedBy/' FileName

答案 4 :(得分:0)

您无法将NR放入END,但您可以这样做:

awk '{a[NR]=$0} /^Date/ {f=NR} END {for (i=f;i<f+4;i++) print a[i]}'
Date: 2014-09-09
Price: 100
Amount: 2.6
ProcessedBy: Boss

它将所有行存储在数组a中,然后将最后Date存储在f中。
END块中,在最后a点击后从数组Date打印四行