sed-从pattern2之前的pattern1删除到pattern2之后的pattern3

时间:2019-07-09 16:10:26

标签: regex awk sed multiline

我正在尝试删除两个模式之间的线,包括带有模式本身的线,如果在它们之间找到了另一个模式,但是我不确定如何解决。

说我有类似以下内容的输入,并想删除#6至#11行,因为在模式notthisstart之间找到了模式end

start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
OgytsRhZbD8T
notthis
0PlcUh2RLvVW
tsz2S80SyW9p
end
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end

我从this answer改变了我的理解,但这种方法不起作用:

/^start$/{$!{N;/^start\n(.*\n)*notthis.*\n(.*\n)*end/d;ty;P;D;:y}}

是因为N仅将初始模式^start$之后的行追加到模式空间,而忽略了随后的内容吗?而实现我想要达到的目标的正确方法是什么?

3 个答案:

答案 0 :(得分:3)

sed用于单个字符串全部上的简单替换。对于其他任何事情,您都应该使用awk,例如对于Gult awk,使用Mult-char RS,这个简短的脚本将从发布的输入中生成所需的输出:

$ awk 'BEGIN{RS=ORS="end\n"} !/notthis/' file
start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end

或更清晰,更强大,更容易通过任何awk进行增强:

$ cat tst.awk
/start/ { f = 1 }
f {
    rec = rec $0 ORS
    if ( /end/ ) {
        if ( rec !~ /notthis/ ) {
            printf "%s", rec
        }
        rec = ""
        f = 0
    }
}
$
$ awk -f tst.awk file
start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end

以上内容将在每个UNIX盒上的任何shell中使用任何awk高效,可靠地工作,易于理解,并且在需求更改时易于修改。

答案 1 :(得分:0)

这是另一个awk脚本。希望匹配部分问题描述。

script.awk

BEGIN {omitMark = "notthis"}  # assign omit marker as ReqExp
/start/, /end/ {   # define RegExp range for omission section 
    if ($0 ~ omitMark) next;  # if matched omission marker skip processing
    print;  # print not ommited currnt line in section
    next;   # skip to process next line in section
}
1;  # print any line not in section.

input.txt

start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
OgytsRhZbD8T
notthis
0PlcUh2RLvVW
tsz2S80SyW9p
end
notthis
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
notthis
end
notthis

运行:

awk -f script.awk input.txt

输出:

start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
OgytsRhZbD8T
0PlcUh2RLvVW
tsz2S80SyW9p
end
notthis
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end
notthis

答案 2 :(得分:0)

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

sed '/^start/{:a;N;/end$/!ba;/notthis/d}' file

收集startend之间的行,如果它们包含字符串notthis,则将其删除。