只删除第一个模式匹配

只删除第一个模式匹配

本文介绍了sed 只删除第一个模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

所以如果这是测试数据:

PATTERNSTARTLINE1LINE2LINE3模式模式开始LINE1LINE2LINE3模式测试线1测试线2测试线3模式开始LINE1LINE2LINE3模式

这将很高兴删除所有模式匹配及其之间的行,但我只想删除第一个模式匹配及其之间的行:

sed '/PATTERNSTART/,/PATTERNEND/d'tested.txt

输出:

TESTLINE1测试线2测试线3

所需输出:

PATTERNSTARTLINE1LINE2LINE3模式测试线1测试线2测试线3模式开始LINE1LINE2LINE3模式

任何 sed 想法?

解决方案

这有点令人难以置信的机器,但它有效:

sed '/PATTERNSTART/,/PATTERNEND/{//{ x;s/$/./;X;};X;/.../!{ X;d;};X;}' 文件名

如下:

/PATTERNSTART/,/PATTERNEND/{ # 在模式范围内//{ # 在第一行和最后一行:Xs/$/./# 在保持缓冲区中增加一个计数器# 给它附加一个字符.柜台是# 保持缓冲区中的字符数.X}x # 对于范围内的所有行:检查# 柜台/.../!{ # 如果不是三个或更多(计数器# 用起始行变成三个# 第二个匹配范围)Xd #删除该行}X}

该代码中的 x 主要是为了确保当整个事情结束时计数器最终回到保持缓冲区中.// 位起作用是因为 // 重复上次尝试的正则表达式,这是其第一行范围的开始模式和其他行的结束模式.>

I would like to match a set of data between two patterns and remove this data and the start/end patterns but only for the first occurrence of the pattern.

So if this is the test data:

PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND
PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND
TESTLINE1
TESTLINE2
TESTLINE3
PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND

This will quite happy remove all the pattern matches and the lines in between but I only want to remove the first pattern match and the lines in between:

sed '/PATTERNSTART/,/PATTERNEND/d' testsed.txt

Output:

TESTLINE1
TESTLINE2
TESTLINE3

Required output:

PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND
TESTLINE1
TESTLINE2
TESTLINE3
PATTERNSTART
LINE1
LINE2
LINE3
PATTERNEND

Any sed ideas?

解决方案

It's a bit incredible-machiney, but this works:

sed '/PATTERNSTART/,/PATTERNEND/ { // { x; s/$/./; x; }; x; /.../! { x; d; }; x; }' filename

as follows:

/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
}

The xs in that code are largely to ensure that the counter ends up back in the hold buffer when the whole thing is over. The // bit works because // repeats the last attempted regex, which is the start pattern of the range for its first line and the end pattern for the others.

这篇关于sed 只删除第一个模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 05:46