![如何删除特定的行以及该行前后的行?](https://linux22.com/image/834522/%E5%A6%82%E4%BD%95%E5%88%A0%E9%99%A4%E7%89%B9%E5%AE%9A%E7%9A%84%E8%A1%8C%E4%BB%A5%E5%8F%8A%E8%AF%A5%E8%A1%8C%E5%89%8D%E5%90%8E%E7%9A%84%E8%A1%8C%EF%BC%9F.png)
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
特殊处理,表示用空行(而不是换行符)分隔记录。