我想匹配两个模式之间的一组数据并删除该数据和开始/结束模式,但仅限于模式的第一次出现。
所以如果这是测试数据:
PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND
PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND
TESTLINE1
TESTLINE2
TESTLINE3
PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND
Run Code Online (Sandbox Code Playgroud)
这将非常高兴地删除所有模式匹配和之间的行,但我只想删除第一个模式匹配和之间的行:
sed '/PATTERNSTART/,/PATTERNEND/d' testsed.txt
Run Code Online (Sandbox Code Playgroud)
输出:
TESTLINE1
TESTLINE2
TESTLINE3
Run Code Online (Sandbox Code Playgroud)
所需输出:
PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND
TESTLINE1
TESTLINE2
TESTLINE3
PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND
Run Code Online (Sandbox Code Playgroud)
有什么 sed 想法吗?
这有点令人难以置信——机械化,但这是有效的:
sed '/PATTERNSTART/,/PATTERNEND/ { // { x; s/$/./; x; }; x; /.../! { x; d; }; x; }' filename
Run Code Online (Sandbox Code Playgroud)
如下:
/PATTERNSTART/,/PATTERNEND/ { # in the pattern range
// { # in the first and last line:
x
s/$/./ # increment a counter in the hold buffer by
# appending a character to it. The counter is
# the number of characters in the hold buffer.
x
}
x # for all lines in the range: inspect the
# counter
/.../! { # if it is not three or more (the counter
# becomes three with the start line of the
# second matching range)
x
d # delete the line
}
x
}
Run Code Online (Sandbox Code Playgroud)
该代码中的sx
主要是为了确保当整个事情结束时计数器最终回到保持缓冲区中。该//
位之所以有效,是因为//
重复了最后一次尝试的正则表达式,这是其第一行范围的开始模式和其他行的结束模式。