如何使用诸如 之类的命令行工具删除从第 n 次出现的模式到文件末尾的内容sed
?例如,从以下
第三个中删除:foo
something
foo1
maybe something else
foo2
maybe not
foo3 -this line and anything after is gone-
I'm not here
$sed '/magic/'
期望的结果:
something
foo1
maybe something else
foo2
maybe not
相同的事情可以获得奖励积分,但保留包含第三个的行foo
。
答案1
不保留线路:
awk -v n=3 '/foo/{n--}; n > 0'
保持线路:
awk -v n=3 'n > 0; /foo/{n--}'
尽管我们可能想稍微改进一下,以便我们一找到第三个就退出并停止阅读foo
:
awk -v n=3 '/foo/{n--; if (!n) exit}; {print}' # not-keep
awk -v n=3 '{print}; /foo/{n--; if (!n) exit}' # keep
sed
会比较麻烦。您需要将 foo 出现次数保留为保留空间中的字符数,例如:
保持:
sed '
/foo/{
x;s/^/x/
/x\{3\}/{
x;q
}
x
}'
不保留:
sed -ne '/foo/{x;s/^/x/;/x\{3\}/q;x;}' -e p
答案2
如果您接受perl
作为命令行工具, 你也可以
perl -ne 'print unless $c>2; ++$c if /foo/'
perl -ne '++$c if /foo/; print unless $c>2'
有/无保留。
答案3
替代答案:你可以从 vim 中做到这一点。您可以使用 vim 作为文本编辑器或命令行工具来完成此操作。作为文本编辑器(带或不带行):
/foo<cr>2ndG:wq<cr>
/foo<cr>2njdG:wq<cr>
一些重要的细节:<cr>
意思是“输入”。另外,您通常应该<n-1>ndG
在“第 N”次出现后删除。你要求 3,所以我在示例中写了 2。
您也可以纯粹从命令行执行此操作。
vim -c "/foo" -c "normal 2ndG" -c "wq"
vim -c "/foo" -c "normal 2njdG" -c "wq"
此方法也适用于正则表达式。这个网站很好地解释了正则表达式的 vim 风格。