sed 在两个模式之间删除,如果没有找到第二个模式,则删除直到结束 [英] sed delete between two patterns deletes until end if second pattern is not found
问题描述
我正在使用 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 nameda
$!{...}
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 theN
command.ba
goto command, breaks to the loop addressa
. 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屋!