如何删除特定的行以及该行前后的行?

如何删除特定的行以及该行前后的行?

history.log我正在对 中的文件进行总结/var/log/apt。为此,我想删除包含某种模式的行以及包含该模式的行之前和之后的行。

在以下示例中:

 1  Start-Date: 2012-10-18  17:34:12
 2  Commandline: /usr/sbin/synaptic
 3  Install: qpdf:i386 (3.0.2-1)
 4  End-Date: 2012-10-18  17:34:21

 5  Start-Date: 2012-10-20  16:56:26
 6  Commandline: apt-get upgrade
 7  End-Date: 2012-10-20  16:56:39

 8  Start-Date: 2012-10-24  09:15:11
 9  Commandline: apt-get upgrade
10  End-Date: 2012-10-24  09:15:26

11  Start-Date: 2012-10-26  18:40:20
12  Commandline: aptdaemon role='role-install-packages' sender=':1.196'
13  Install: gcolor2:i386 (0.4-2.1ubuntu1)
14  End-Date: 2012-10-26  18:40:31

15  Start-Date: 2012-10-27  07:20:03
16  Commandline: apt-get upgrade
17  End-Date: 2012-10-27  07:20:11

18  Start-Date: 2012-10-29  16:32:33
19  Commandline: /usr/sbin/synaptic
20  Install: policykit-desktop-privileges:i386 (0.12)
21  End-Date: 2012-10-29  16:32:40

我想要删除第 5、6 和 7 行、第 8、9 和 10 行以及第 15、16 和 17 行。

我所能做的就是sed -rs ''/apt-get\ upgrade/,+1'd;'删除包含该行的行apt-get upgrade和其后的行。

答案1

好吧,虽然有些丑陋,但可以工作:

pattern="apt-get\ upgrade"
prog="BEGIN {b=0} /$pattern/ {print; b=1; next} {if (b==1) {b=0;next;} else {print;}}"
cat test | awk "$prog" | tac | awk "$prog" |tac | grep -v "$pattern"

第二行创建一个 awk 程序,删除找到模式的行后面的行。

然后,在测试文件上运行该程序,输出被反转,再次运行程序,输出被反转,并且删除带有模式的线条。

更短一些,但采用同样的方法:

cat test | sed -e "/$pattern/{n;d}" | tac | sed -e "/$pattern/,+1d" |tac

我认为对文件进行逆向分析是强制性的,因为据我所知,流处理工具无法落后

答案2

目前尚不清楚您想要它有多通用,但awk执行此特定任务的可能是:

awk 'BEGIN{ RS=""; ORS="\n\n"; } !/apt-get upgrade/' /var/log/apt/history.log

你可以用更多的模式来扩展它

awk 'BEGIN{ RS=""; ORS="\n\n"; } !/apt-get upgrade/ && !/apt-get install hello/' /var/log/apt/history.log

它的工作原理是将记录分隔符RS(默认情况下为换行符)设置为空字符串。空字符串经过RS特殊处理,表示用空行(而不是换行符)分隔记录。

相关内容