shell 我想在匹配条件后从日志文件中删除几行

w46czmvw  于 2023-08-07  发布在  Shell
关注(0)|答案(3)|浏览(83)

我有一个巨大的日志文件,我想删除从---Successful backups---开始的行,直到---Failed backups---行开始。然后,再次使用shell脚本删除从---Unresolved clients---开始直到---Summary notification report---的行。下面是几个日志的示例。请指教。

---Summary notification report--- Policy name:xyz
        Workflow name:abc1, Workflow status:succeeded, Workflow start time:08/01/23 14:30:00, Duration:0 hours 0 minutes 33 seconds
                Action name:backup, Action status:succeeded, Action start time:08/01/23 14:30:00, Duration:0 hours 0 minutes 33 seconds
--- Traditional Backup Action report --- Policy name:xyz Workflow name:abc1 Action name:backup Action status:succeeded Action start time:08/01/23 14:35:00 Action duration:0 hours 0 minutes 30 seconds Total 1 client(s), 0 Succeeded with warning(s), 1 Succeeded, 0 Failed, 0 Unresolved.
        ---Successful backups---
        abc.net:PIP, level=incr, size 96 KB, duration 0 hours 0 minutes 14 seconds, 5 files
        abc.net:SYBASE:/PIP/master.1, level=full, size 20 MB, duration 0 hours 0 minutes 2 seconds, 1 files
        ---Successful backups with warnings---
        none
        ---Failed backups---
        none
        ---Unresolved clients---
        none
---Summary notification report---

字符串
我正在尝试使用grep命令,但没有得到正确的结果。

cat log.out | grep -A 7 'Action name:backup, Action status:failed, Action start time:08/01/23'

lvjbypge

lvjbypge1#

如果“until starting with line "---Failed backups---"”意味着从开始删除但停止且不删除这一行,("---Summary notification report---"也是如此),那么您可以通过切换一个控制是否删除(跳过)打印记录的标志来相当容易地使用awk。例如,您可以执行以下操作:

awk '
  # set del flag 1, skip to next record (line)
  /^[[:space:]]*---Successful backups---/ { del=1; next }
  # set del flag 0
  /^[[:space:]]*---Failed backups---/ { del=0 } 
  # set del flag 1, skip to next record (line)
  /^[[:space:]]*---Unresolved clients---/ { del=1; next } 
  # set del flag 0
  /^[[:space:]]*---Summary notification report---$/ { del=0 } 
  # if del set, skip printing record
  del {next}
  # otherwise print
  {print}
' dat/log

字符串
在这里,您只需使用正则表达式来调节每个规则({ ... }之间的命令),以匹配开始行和停止行。del标志控制是否跳过该行(不打印)。当匹配包含开始规则的记录时,打开del标志(不打印该行),当达到结束规则时,关闭del标志(输出该记录)。您可以在正则表达式之间使用||(OR)条件合并on和off规则,但这会使其可读性稍差。

使用/输出示例

dat/log文件中有了示例数据,您可以在数据文件的目录(或提供完整路径)中,在提示符处粘贴命令,例如:

$ awk '
>   # set del flag 1, skip to next record (line)
>   /^[[:space:]]*---Successful backups---/ { del=1; next }
>   # set del flag 0
>   /^[[:space:]]*---Failed backups---/ { del=0 }
>   # set del flag 1, skip to next record (line)
>   /^[[:space:]]*---Unresolved clients---/ { del=1; next }
>   # set del flag 0
>   /^[[:space:]]*---Summary notification report---$/ { del=0 }
>   # if del set, skip printing record
>   del {next}
>   # otherwise print
>   {print}
> ' dat/log
---Summary notification report--- Policy name:xyz
        Workflow name:abc1, Workflow status:succeeded, Workflow start time:08/01/23 14:30:00, Duration:0 hours 0 minutes 33 seconds
                Action name:backup, Action status:succeeded, Action start time:08/01/23 14:30:00, Duration:0 hours 0 minutes 33 seconds
--- Traditional Backup Action report --- Policy name:xyz Workflow name:abc1 Action name:backup Action status:succeeded Action start time:08/01/23 14:35:00 Action duration:0 hours 0 minutes 30 seconds Total 1 client(s), 0 Succeeded with warning(s), 1 Succeeded, 0 Failed, 0 Unresolved.
        ---Failed backups---
        none
---Summary notification report---


让我知道如果你需要跳过你的停止线或删除你的开始线。你是打算“包容”还是“排斥”要删除的内容有点模棱两可。要更改行为,请在规则中添加或删除next,以跳过或打印开始/停止行。

kuarbcqp

kuarbcqp2#

使用sed

sed -e '/---Successful backups---/,/---Failed backups---/{/---Failed backups---/!d}' -e '/---Unresolved clients---/,/---Summary notification report---/{/---Summary notification report---/!d}' log.out

字符串

  • /addr1/,/addr2/将从匹配addr1的行匹配到匹配addr2的行
  • /addr/!如果行不匹配addr
  • d删除
e3bfsja2

e3bfsja23#

使用TXR Lisp awk宏,可以直接完成此操作,而无需任何状态标志:

$ txr -e '(awk ((or (rng- #/---Successful backups---/
                          #/---Failed backups---/)
                    (rng- #/---Unresolved clients---/
                          #/---Summary notification report---/))
                (next))
               (t))'   < infile > outfile

字符串
Awk范围语法from, to看起来像(rng from to)。但是,还有两个不同之处:

  1. rng操作符有九种不同的有用的风格。
    1.范围表达式可以用作较大表达式中子表达式,而这在常规Awk中是不允许
    在上面的解决方案中,我们使用rng-排除结束记录,并使用(or ...)宏将我们要排除的两个范围合并到单个表达式中。对于这些范围,我们调用(next)以转到下一个记录。否则,控制权福尔斯到(t)子句,该子句有一个无条件为真的条件t和一个空操作,因此默认操作是(prn)以打印记录。

相关问题