作者lemonsheep (柠檬羊)
看板Linux
标题[问题] 删除匹配pattern的前几行
时间Sat Dec 5 00:01:57 2020
想请问如果想要删除档案中 match 到的 pattern 的前几行要用甚摸指令?
例如:
Aaaa
Bbbb
Snnn
我知道在 vim 中的话可以用 :g/Snnn/-2,-1d
但如果用 command line 的话就不大知道怎摸达到这样的效果
有试过 sed 但 sed 似乎只能删除 match 到的 pattern 的後几行
想请教各位大大有没有比较好的方法可以达成这个目的?
感谢
===== 更新 =====
感谢推文的大大们提示
目前尝试过後有发现一个可行的方式了,就是先反转档案内容再删除 matched line 的後几行 然後再反转档案,不知道还有没有更精简的作法~
# 反转档案
sed '1!G;h;$!d' file or tac file
# 删除 match 到的 pattern 的後 2 行 (包含 matched line)
sed '/Snnn/,+2d' file
# 删除 match 到的 pattern 的後 2 行 (不包含 matched line)
sed '/Snnn/{n;N;d}' file
# 反转档案 -> 删除 matched line 後 2 行 -> 反转档案
sed '1!G;h;$!d' file | sed '/Snnn/,+2d' | sed '1!G;h;$!d' > file (包含 matched line)
sed '1!G;h;$!d' file | sed '/Snnn/{n;N;d}' | sed '1!G;h;$!d' > file (不包含 matched line)
但在"不包含 matched line" 的作法中似乎无法直接指定要读入後几行,要删除几行就必须要几个 "N",不晓得还有没有更好的作法~
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 180.177.3.109 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Linux/M.1607097719.A.18E.html
1F:→ Typebrook: 关键字: hold space,欢迎进入sed的烧脑领域 12/05 12:40
2F:推 ucrxzero: grep -A 12/05 13:04
3F:推 ucrxzero: awk if匹配後狂print 12/05 15:57
※ 编辑: lemonsheep (180.177.3.109 台湾), 12/05/2020 20:16:11
4F:推 Gold740716: 用 vim 的 scripting 模式吧,或用 ed 12/06 23:08
5F:推 Gold740716: ex -c ':g/Snnn/-2,-1d' -c ':wq' file.txt 12/06 23:12
6F:→ Gold740716: 喔可以加个 -s 选项 12/06 23:13
7F:→ Gold740716: 因为你要做的事本质需要在档案中来回移动,所以用 sed 12/06 23:13
8F:→ Gold740716: 会很不方便,sed 是用来处理串流的,只能前进不能回头 12/06 23:14
9F:推 Gold740716: or printf '%s\n' :g/Snnn/-2,-1d :wq | ex -s file.t 12/06 23:16
哇 这招很厉害,比 sed 方便多了, 感谢大大。
这样应该是一次一行指令被 pipe 传到 ex
※ 编辑: lemonsheep (180.177.3.109 台湾), 12/07/2020 22:14:46
10F:推 Gold740716: sed ':rn; N; s/\n/\n/3; t c; b rn; :c s/\n/\t/g' 12/16 18:01
11F:→ Gold740716: sed 的 s///3 可以取代第 n 个,取代 \n 就能判断是否 12/16 18:02
12F:→ Gold740716: 存在 3 个 \n 。 12/16 18:02
13F:→ Gold740716: 但实际上不会比较好写 12/16 18:02