单行打印两个图案之间的所有线条

问题描述 投票:3回答:4

使用一行Perl代码,在两个模式之间打印所有行的最短路径是什么,不包括带有模式的行?

如果这是file.txt:

aaa
START
bbb
ccc
ddd
END
eee
fff

我想打印这个:

bbb
ccc
ddd

我可以使用这样的方式获得大部分方式:

perl -ne 'print if (/^START/../^END/);'

这包括STARTEND线。

我可以像这样完成工作:

perl -ne 'if (/^START/../^END/) { print unless (/^(START)|(END)/); };' file.txt

但这似乎是多余的。

我真正想做的是使用lookbehind和lookahead断言,如下所示:

perl -ne 'print if (/^(?<=START)/../(?=END)/);' file.txt

但这不起作用,我认为我的正则表达式中有一些错误。

这些只是我试过的一些不产生输出的变化:

perl -ne 'print if (/^(?<=START)/../^.*$(?=END)/);' file.txt
perl -ne 'print if (/^(?<=START)/../^.*(?=END)/);' file.txt
perl -ne 'print if (/^(?<=START)/../(?=END)/);' file.txt
perl -ne 'print if (/^(?<=START)/../.*(?=END)/);' file.txt
perl -ne 'print if (/^(?<=START)/../^.*(?=END)/);' file.txt
perl -ne 'print if (/^(?<=START)/../$(?=END)/);' file.txt
perl -ne 'print if (/^(?<=START)/../^(?=END)/);' file.txt
perl -ne 'print if (/^(?<=START)/../(?=^END)/);' file.txt
perl -ne 'print if (/^(?<=START)/../.*(?=END)/s);' file.txt
regex perl regex-lookarounds
4个回答
3
投票

阅读整个文件,匹配并打印。

perl -0777 -e 'print <> =~ /START.*?\n(.*?)END.*?/gs;' file.txt

如果单独上线,可能会在.*?之后放下START|END。然后将\n放在段之间的空白行。


读取文件,由START|END分割线,打印每个奇数的@F

perl -0777 -F"START|END" -ane 'print @F[ grep { $_ & 1 } (0..$#F) ]' file.txt

使用END { }块进行额外处理。使用}{END { }

perl -ne 'push @r, $_ if (/^START/../^END/); }{ print "@r[1..$#r-1]"' file.txt

仅适用于文件中的单个此类段。


1
投票

对此进行单行限制似乎有点武断,但这是一种方法:

$ perl -wne 'last if /^END/; print if $p; $p = 1 if /^START/;' file.txt

1
投票
perl -e 'print split(/.*START.|END.*/s, join("", <>))' file.txt

perl -ne 'print if /START/../END/' file.txt | perl -ne 'print unless $.==1 or eof'

perl -ne 'print if /START/../END/' file.txt | sed -e '$d' -n -e '1\!p'

1
投票

我不明白为什么你如此坚持使用外观,但这里有几种方法可以做到。

perl -ne 'print if /^(?=START)/../^(?=END)/'

这会找到终结符而不实际匹配它们。满足前瞻的零长度匹配是匹配的。

你的lookbehind无法正常工作,因为它试图在^之前找到START线的开头,然后它就在同一条线上,这显然永远不会匹配。将^纳入零宽度断言,它将起作用:

perl -ne 'print if /(?<=^START)/../(?<=^END)/'

正如@ThisSuitIsBlack的评论中所建议的那样,您可以使用序列号来省略STARTEND令牌。

perl -ne '$s = /^START/../^END/; print if ($s>1 && $s !~ /E0/)'

外观没有任何用处,所以我没有完全开发这些例子。如果您更关心使用外观而不是代码可维护性和执行速度,那么您可以将其调整为上面的一个示例。

© www.soinside.com 2019 - 2024. All rights reserved.