sed 仅删除第一个模式匹配

Sna*_*Man 5 sed

我想匹配两个模式之间的一组数据并删除该数据和开始/结束模式,但仅限于模式的第一次出现。

所以如果这是测试数据:

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 想法吗?

Win*_*ute 4

这有点令人难以置信——机械化,但这是有效的:

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主要是为了确保当整个事情结束时计数器最终回到保持缓冲区中。该//位之所以有效,是因为//重复了最后一次尝试的正则表达式,这是其第一行范围的开始模式和其他行的结束模式。