使用 sed 删除多行字符串的简单方法
Posted
技术标签:
【中文标题】使用 sed 删除多行字符串的简单方法【英文标题】:Simple way to remove multi-line string using sed 【发布时间】:2021-11-18 17:41:37 【问题描述】:使用 sed,有没有办法根据一些开始和结束表达式从文本文件中删除多行?
我知道文件中的标记,并想删除(包括标记)之间的所有内容。我已经看到了一些非常复杂的解决方案,我想在不求助于微命令的情况下做到这一点。
我的文件看起来像这样:
cat /tmp/foobar.txt
this is line 1
this is line 3
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=\
annotations-api.jar,\
ant-junit*.jar,\
ant-launcher.jar,\
ant.jar,\
asm-*.jar,\
aspectj*.jar,\
bootstrap.jar,\
catalina-ant.jar,\
catalina-ha.jar,\
catalina-ssi.jar,\
catalina-storeconfig.jar
the end leave me
and me
我想删除从 tomcat.util
开始到最后一个 .jar
的所有内容
【问题讨论】:
【参考方案1】:tldr;
我认为这是最简单的方法,不需要像微命令这样的程序集
sed '/^tomcat\.util.*$/,/^.*[^\]$/d' /tmp/foobar.txt
产生
this is line 1
this is line 3
the end leave me
and me
如果您想删除文件中的行而不是将输出输出到标准输出,请使用inline
标志,所以
sed -i '/^tomcat\.util.*$/,/^.*[^\]$/d' /tmp/foobar.txt
那么...这是如何工作的?
sed
命令,如vi
命令在address
上运行。通常我们不指定地址,而只是将命令应用于文件的所有行,例如,在我们通常会做的文件中将the
替换为that
时
sed -i 's/the/that/g' /tmp/foobar.txt
即对文件中的所有行应用替换或s
命令。
在这种情况下,您希望删除一些行,以便我们可以使用 delete 或 d
命令。但是我们需要告诉它在哪里删除。所以我们需要给它一个地址。
sed
命令的格式是
[addr][!]command[options]
(见the docs)
如果没有指定地址,则该命令应用于所有行,如果指定了!
,则该命令应用于所有与该模式不匹配的行。到目前为止一切顺利。
这里的诀窍是addr
可以是单个地址或地址范围。地址可以是行号或正则表达式模式。您在两个地址之间使用,
来指定范围。
所以你可以删除第 5 到 8 行(包括)
sed -i '5,8d' /tmp/foobar.txt
在这种情况下,我们知道一些“标记”,而不是知道行号,我们可以使用正则表达式,所以第一个标记,以tomcat.util
开头的行被正则表达式找到
/^tomcat\.util.*$/
第二个标记有点棘手,但如果我们看一下,我们可以看到要删除的最后一行是第一个不以 \
结尾的行,因此我们可以匹配包含“除了不以\
结尾"
/^.*[^\]$/
虽然如果我们从这两个正则表达式中创建一个范围,第二个标记可以匹配一大堆行,但该范围意味着第二个“地址”是与正则表达式匹配的第一个地址之后的第一行。
综上所述,我们要删除 (d
) 范围内的所有行987654347@即
sed '/^tomcat\.util.*$/,/^.*[^\]$/d' /tmp/foobar.txt
希望有帮助 ;-)
干杯
卡尔
【讨论】:
不用担心。干杯。 当tomcat.util
行不以 `` 结尾时,下一行也会被删除。【参考方案2】:
对于跨行的任何内容,Awk 通常比 sed 更有用。在每个 Unix 机器上的任何 shell 中使用任何 awk:
$ awk '!/\.jar/f=0 /tomcat\.util/f=1 !f' file
this is line 1
this is line 3
the end leave me
and me
【讨论】:
谢谢!这也有效。我不得不说我什至没有想到awk
,你说得对,这个解决方案既好又干净。【参考方案3】:
这可能对你有用(GNU sed):
sed -n '/tomcat\.util/:a;n;/\.jar/ba;p' file
使用-n
选项关闭隐式打印。
匹配包含tomcat.util
的行。
继续获取行,直到这样的行与包含 .jar
的行不匹配。
打印所有其他行。
替代方案:
sed -E '/tomcat\.util/:a;$!N;/\.jar(,\\)?$/s/\n//;ta;D' file
收集以tomcat.util
开头并以.jar,\
或.jar
结尾的行,删除换行符直到文件结尾或不匹配,然后删除该集合。
【讨论】:
以上是关于使用 sed 删除多行字符串的简单方法的主要内容,如果未能解决你的问题,请参考以下文章