sed 在两个模式之间删除,如果没有找到第二个模式,则删除直到结束 [英] sed delete between two patterns deletes until end if second pattern is not found

查看:49
本文介绍了sed 在两个模式之间删除,如果没有找到第二个模式,则删除直到结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 sed 删除配置文件中的标签,但我无意中发现了一个问题,为此我将使用一个基本示例:

I'm using sed to remove tags in a configuration file, but I accidentally stumbled upon a problem, for which I'll use a basic example:

numbers.txt 文件的内容:

0
1
2
3
4
5
6
7
8
9

在两个数字之间删除(包括数字本身):

Delete between two numbers (including the numbers themselves):

sed '/4/,/6/d' numbers.txt

收益(如预期):

0
1
2
3
7
8
9

但是如果我从 numbers.txt 中删除 6 行,我希望相同的命令产生 all numbers.txt 因为它找不到第二个模式,而是简单地删除 4 行之后的所有内容(大概是因为对 6 的搜索到达了文件,所以这就是它返回的值):

But if I remove the 6 line from numbers.txt, I would expect the same command to yield all of numbers.txt since it cannot find the second pattern, but instead it simply deletes everything after the 4 line (presumably because the search for 6 reached the end of the file, so that's the value it returns):

0
1
2
3

我的问题是:如何修改 sed 语句以在此类事件中不执行任何操作?

My question is: how do I modify the sed statement to simply do nothing in such an event?

推荐答案

这可能对你有用(GNU sed):

This might work for you (GNU sed):

sed '/4/{:a;$!{N;/6/Md;ba}}' file

构建自己的循环,如果满足结束条件,则只删除模式空间中累积的行.

Build your own loop and only delete the accumulated lines in the pattern space if the end condition is met.

注意结束条件上的 M 标志允许在模式空间中收集的多行上进行匹配.

N.B. The M flag on the end condition to allow matches on multiple lines gathered up in the pattern space.

/start/,/end/d 是一个控制结构,一旦找到 start 立即删除行直到 end 或结束文件.因此有两个end条件,地址/end/$.由于动作(在本例中删除)是即时的,如果不满足/end/条件,则无法撤消,因此需要将要删除的行收集起来删除或不删除取决于两个条件之一,/end/(删除)或 $(不删除).

The /start/,/end/d is a control structure that upon finding start immediately deletes lines until end or the end of the file. Therefore there are two end conditions, the address /end/ or $. As the action (in this case deletion) is immediate, it can not be reversed if the /end/ condition is not met, for this reason the lines to be deleted need to gathered up and deleted or not depending on one of two conditions, either /end/( delete) or $ (do not delete).

  • /4/{...} 大括号内动作的起始地址.
  • :a 名为 a
  • 的循环的起始地址
  • $!{...} 如果不是花括号内的文件操作结束.
  • N 在模式空间中追加一个换行符和下一行.
  • /6/Md 结束地址和删除命令(如果找到),即这将删除模式空间中由 N 命令附加的所有行.
  • ba goto 命令,中断到循环地址a.这使循环机制能够继续,直到两个条件 /6/$ 之一.
  • /4/{...} start address of actions within the curly braces.
  • :a the address of the start of a loop named a
  • $!{...} if not the end of file actions within the curly braces.
  • N append a newline and then the next line to the pattern space.
  • /6/Md end address and delete command if found i.e. this will delete all lines in the pattern space that have been appended by the N command.
  • ba goto command, breaks to the loop address a. This enables the loop mechanism to continue until one of two conditions /6/ or$.

注意如果满足文件结束条件,则 /4/{...} 结束,并正常打印累积的行.

N.B. If the end of file condition is met, the /4/{...} ends and the accumulated lines are printed as normal.

这篇关于sed 在两个模式之间删除,如果没有找到第二个模式,则删除直到结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆