【问题标题】:sed and grep get the line number for a matchsed 和 grep 获取匹配的行号
【发布时间】:2013-11-28 17:15:36
【问题描述】:

我有一个日志文件,我使用 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

【问题讨论】:

    标签: bash sed grep


    【解决方案1】:

    你可以使用:

    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 ...
    

    【讨论】:

    • cat -n插入的行号可能很容易干扰sedgrep等执行的操作,至少在一般情况下。
    【解决方案2】:

    我的第一次尝试没有保留行号,因为 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 文本时关闭标志。

    【讨论】:

    • 我需要原始文件中的行号。在你的输出中:第 5 行和第 6 行而不是第 4 行和第 5 行。我用 cat -n 做了。谢谢。
    • 哦,现在我完全理解了,@georgiana_e。只是为了完整起见,我完全改变了我的答案,以便它真正满足需要。
    【解决方案3】:
    sed -n '/TST STARTS/,/TST FINISHED/ {
       /MATCH/ {
          =;p
          }
       }' log.txt
    

    行号比下一行的行内容

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

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

    【讨论】:

      猜你喜欢
      • 2017-05-30
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      • 2016-10-08
      • 2019-04-30
      • 1970-01-01
      • 2021-06-06
      相关资源
      最近更新 更多