12

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

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

我使用这个命令来提取行:

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

我的输出是:

MATCH str3
MATCH str4

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

line 5: MATCH str3
line 6: MATCH str4
4

3 回答 3

19

你可以使用:

cat -n

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

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

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

nl -n ln log.txt | sed ...
于 2013-11-15T10:37:28.220 回答
5

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

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

$ awk '/TST STARTS/ {p=1} p && /MATCH/ {print "line "NR" --> "$0}; /TST FINISHED/ {p=0}' a
line 5 --> MATCH str3 //line 5
line 6 --> MATCH str4 //line 6
  • '/TST STARTS/ {p=1}设置一个标志p=1,以便从现在开始考虑所有行。
  • p && /MATCH/ {print "line "NR" --> "$0}如果标志p处于活动状态并且该行包含MATCH,则它会打印信息。
  • /TST FINISHED/ {p=0}TST FINISHED查找文本时关闭标志。
于 2013-11-15T10:34:30.313 回答
3
sed -n '/TST STARTS/,/TST FINISHED/ {
   /MATCH/ {
      =;p
      }
   }' log.txt

行号比下一行的行内容

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

包含在同一行(可以在 1 个 sed 中完成,但在这种情况下,脚本巨大且性能不佳,从 shell 召回事件,使用第二个 sed 更容易)。也可以与先前的行号一起使用

于 2013-11-15T10:51:43.473 回答