bash sed 和 grep 获取匹配的行号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19998927/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:25:52  来源:igfitidea点击:

sed and grep get the line number for a match

bashsedgrep

提问by georgiana_e

I have a log file and i use sed to extract the lines between two strings which contains the word MATCH. I use sed to extract the lines and grep to only take the lines containing the word "MATCH". I would need the lines number in the log file where a match is found.

我有一个日志文件,我使用 sed 来提取包含单词 MATCH 的两个字符串之间的行。我使用 sed 提取行并使用 grep 只提取包含“MATCH”一词的行。我需要日志文件中找到匹配项的行号。

Date:...
TST STARTS
DISCARD str1
DISCARD str2
MATCH str3 //line 5
MATCH str4 //line 6
DISCARD str5
TST FINISHED

I use this command to extract the lines:

我使用此命令来提取行:

sed -n "/TST STARTS/,/TST FINISHED/p" log.txt | grep "MATCHED".

My output is:

我的输出是:

MATCH str3
MATCH str4

But I also need in the output the lines number:

但我还需要在输出中的行数:

line 5: MATCH str3
line 6: MATCH str4

回答by Mark Setchell

You could use:

你可以使用:

cat -n

to number the lines before you apply your sed, like this:

在应用 sed 之前对行进行编号,如下所示:

cat -n log.txt | sed -n "/TST STARTS/,/TST FINISHED/p" | grep "MATCHED"

Alternatively, you could replace cat -nwith a variant of nl:

或者,您可以替换cat -n为以下变体nl

nl -n ln log.txt | sed ...

回答by fedorqui 'SO stop harming'

My first attempt wasn't keeping the line number, because the sedpart removes certain lines.

我的第一次尝试没有保留行号,因为该sed部分删除了某些行。

Everything can be done with this awk:

一切都可以用这个来完成awk

$ awk '/TST STARTS/ {p=1} p && /MATCH/ {print "line "NR" --> "
sed -n '/TST STARTS/,/TST FINISHED/ {
   /MATCH/ {
      =;p
      }
   }' log.txt
}; /TST FINISHED/ {p=0}' a line 5 --> MATCH str3 //line 5 line 6 --> MATCH str4 //line 6
  • '/TST STARTS/ {p=1}sets a flag p=1so that from now on all lines will be taken into account.
  • p && /MATCH/ {print "line "NR" --> "$0}if the flag pis active and the line contains MATCH, then it prints the info.
  • /TST FINISHED/ {p=0}turns the flag off when finding TST FINISHEDtext.
  • '/TST STARTS/ {p=1}设置一个标志,p=1以便从现在开始考虑所有行。
  • p && /MATCH/ {print "line "NR" --> "$0}如果标志p处于活动状态并且该行包含MATCH,则它会打印信息。
  • /TST FINISHED/ {p=0}查找TST FINISHED文本时关闭标志。

回答by NeronLeVelu

| sed "/^[0-9]/ { 
  N
  s/^\(.*\)\n/line :/
   }"

line number than the line content on next line

行号比下一行的行内容

##代码##

for inclunding on same line (could be done in 1 sed but huge script and poor performance in this case, event with a recall from shell it's easier with a second sed). Could also be don with a previous numbering of line

包括在同一行上(可以在 1 个 sed 中完成,但在这种情况下,巨大的脚本和糟糕的性能,从 shell 召回事件,使用第二个 sed 更容易)。也可以使用先前编号的行