【问题标题】:How to print nth line from the pattern?如何从模式中打印第 n 行?
【发布时间】:2013-09-25 10:40:50
【问题描述】:

我正在尝试制作一个脚本来总结一个包含以下短格式日志的文件。

日志片段:

$ cat input.txt
ffffff     1301 2012-08-29T03:13:33 clr         crit
Some serious problem
cccc                            dddddd        eeeeee
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Some serious problem in system.

ffffff     1302 2012-08-29T03:13:33 set         min
Some serious problem
cccc                            dddddd        eeeeee
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Some minor problem in system. 

期望的输出:

2012-08-29T03:13:33 clr crit Some serious problem in system.
2012-08-29T03:13:33 set min Some minor problem in system. 

我尝试了以下方法:

$ cat input.txt | grep -iE "set|upd|clr" | awk '{print $3,$4,$5}' >file1
12-08-29T03:13:33  clr crit
12-08-29T03:13:33  set min

下面的命令给了我模式“T”的第 5 行,但问题在于所需的文本行,在某些情况下它在第 5 行,在某些情况下它在第 4 行。

$ awk '/T/ { show[NR+4]++  } show[NR]' input.txt >file2

$ paste file1 file2 

查询:

在某些情况下它在第 5 行,在某些情况下它在第 4 行。我怎样才能确保找到确切的文本。如果可能,请告诉我。

【问题讨论】:

    标签: linux bash sed awk grep


    【解决方案1】:

    解决这个问题的正确方法就是将 awks Record Separator 设置为空字符串,以便 awk 知道您的输入记录由空行分隔:

    $ awk -v RS= -F'\n' '{split($1,a,/ +/); print a[3],a[4],a[5],$NF}' file
    2012-08-29T03:13:33 clr crit Some serious problem in system.
    2012-08-29T03:13:33 set min Some minor problem in system.
    

    这样,如果/当您想在将来打印记录的其他部分或打印记录数或仅根据某些关键字段或其他内容打印唯一记录时,这绝对是微不足道的,因为 awk 知道并且是对记录进行操作。

    【讨论】:

      【解决方案2】:

      您的记录大小似乎固定为 7 行,因此您可以使用 awk 执行以下操作:

      $ awk 'NR%7==1{printf "%s %s %s ",$3,$4,$5}NR%7==6' file
      2012-08-29T03:13:33 clr crit Some serious problem in system.
      2012-08-29T03:13:33 set min Some minor problem in system.
      

      这使用模运算符在记录的第一行打印第三、第四和第五个字段,并打印整个第六行。

      【讨论】:

        【解决方案3】:

        这个awk单行应该更健壮:

        awk '$3 ~ /[0-9]+-[0-9]+-/{printf "%s%s%s%s%s", $3, OFS, $4, OFS, $5; 
             for(i=0; i<5; i++) getline; print OFS $0}' input.txt
        
        2012-08-29T03:13:33 clr crit Some serious problem in system.
        2012-08-29T03:13:33 set min Some minor problem in system.
        

        UPDATE:: 没有 getline 的解决方案:

        awk '$3 ~ /[0-9]+-[0-9]+-/{s=NR; printf "%s%s%s%s%s", $3, OFS, $4, OFS, $5}
             NR==s+5{print OFS $0}' input.txt
        

        【讨论】:

        • 使用getline 永远不会健壮。
        猜你喜欢
        • 1970-01-01
        • 2013-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-13
        • 1970-01-01
        • 1970-01-01
        • 2023-02-03
        相关资源
        最近更新 更多