Regex sed-从模式2之前的模式1删除到模式2之后的模式3
如果在两个模式之间发现另一个模式,我会尝试删除两个模式之间的线条,包括带有模式本身的线条,但我不确定如何处理它 假设我有如下输入,并希望删除第6行到第11行,因为模式Regex sed-从模式2之前的模式1删除到模式2之后的模式3,regex,awk,sed,multiline,Regex,Awk,Sed,Multiline,如果在两个模式之间发现另一个模式,我会尝试删除两个模式之间的线条,包括带有模式本身的线条,但我不确定如何处理它 假设我有如下输入,并希望删除第6行到第11行,因为模式notthis位于模式start和end之间: start AHBUe3Ar5NoD 3EcuCcD2QCja 7VmlKFbD8Rbi end start OgytsRhZbD8T notthis 0PlcUh2RLvVW tsz2S80SyW9p end start dQ5qiZCvBqcK SufdS40X1Sh2 B1cyN
notthis
位于模式start
和end
之间:
start
AHBUe3Ar5NoD
3EcuCcD2QCja
7VmlKFbD8Rbi
end
start
OgytsRhZbD8T
notthis
0PlcUh2RLvVW
tsz2S80SyW9p
end
start
dQ5qiZCvBqcK
SufdS40X1Sh2
B1cyNshOj2Z4
end
我把我认为我理解的东西改成了这样的东西,但它不起作用:
/^start$/{$!{N;/^start\n(.*\n)*notthis.*\n(.*\n)*end/d;ty;P;D;:y}}
是否因为
N
只将初始模式^start$
后面的行附加到模式空间,而忽略后面的内容?那么,实现我想要的目标的正确方法是什么呢?sed是对单个字符串的简单替换,就是这样。对于任何其他您应该使用awk的内容,例如GNU awk For 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都能高效、可靠地工作,并且易于理解,并且在您的需求发生变化时进行修改。下面是另一个
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
这可能适用于您(GNU-sed):
收集
start
和end
之间的行,如果它们包含字符串notthis
请删除它们。希望在编写一个包含符文的脚本时会出现这样的情况,比如/^start$/{$!{N;/^start\N(.\N)*notthis.\N(.\N)*end/d;ty;p;d;:y}
当你想一想——“我在干什么?”!谢谢你,很有魅力。请您解释一下这两种方法好吗?第一种方法每次读取一整条记录(多行文本块),其中每条记录以end\n
结尾,如果不包含notthis
,则打印该记录。第二个在找到start
时设置一个标志,在设置该标志时一次建立一行记录,然后在找到end
时,如果记录不包含notthis
,则打印该记录。在浏览awk手册页后,如果您对语法有任何具体问题,请告诉我。如果您考虑使用范围表达式,请确保理解上的讨论。
sed '/^start/{:a;N;/end$/!ba;/notthis/d}' file