我有以下文字
Start
bla
bla
bla
end
Start
bla
bla
MATCH
bla
end
Start
bla
bla
bla
end
我只需要下面的
Start
bla
bla
MATCH
bla
end
用英文写的。在两个模式之间打印行,其中包括一个匹配字符串。
尝试
awk '/Start /,/End/' file
perl -lne 'print if /start/ .. /end/' file
无法在标签之间进行匹配
首选需要一个班轮命令
答案 0 :(得分:1)
将输入记录分隔符(from inspect import signature
def decorator(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
wrapper.__signature__ = signature(f)
return wrapper
)设置为$/
,然后对end\n
的正则表达式检查将检查MATCH
和Start
之间的每个部分为如果它是单行。
end\n
答案 1 :(得分:1)
您遇到的问题是您的范围运算符仍然可以逐行运行。
E.g。
while ( <> ) {
print if m/start/i .. m/end/i;
}
仍然使用记录分隔符作为\n
- 循环的每次迭代都将从文件中读取另一行,但您无法匹配整个块...因为它可能不会已经预知到目前为止。
你可以通过正则表达式匹配&#39;开始..结束&#39;块:
#!/usr/bin/env perl
use strict;
use warnings;
my @chunks = do { local $/; <DATA> =~ m/Start.*?end/mgs };
print grep { m/MATCH/ } @chunks;
__DATA__
Start
bla
bla
bla
end
Start
bla
bla
MATCH
bla
end
Start
bla
bla
bla
end
或者作为另一张海报备注 - 将$/
设置为&#39;结束&#39;。这有一点点缺点,因为它会忽略“开始”,这意味着如果您没有正确匹配,可能会获得额外的内容。
您也可以尝试:
local $/ = "end\nStart";
哪个会正确分割您的数据,但是再次 - 可能无法正确处理所有方案。
#!/usr/bin/env perl
use strict;
use warnings;
local $/ = "end\nStart";
while ( <DATA> ) {
chomp;
print "Chunk: $_\n";
print "----\n";
print "Matches!\n" if m/MATCH/;
}
这些可以单行:
perl -lne 'BEGIN { $/ = "end\nStart" } print if /MATCH/' file
答案 2 :(得分:0)
要求救援
awk 'BEGIN {ORS=RS="end\n"} /MATCH/'
按照定义设置记录分隔符并查找匹配的记录。如果不需要多个匹配,则只打印第一个匹配。
awk 'BEGIN {ORS=RS="end\n"} /MATCH/{print;exit}'
答案 3 :(得分:0)
假设:
$ echo "$tgt"
Start
bla
bla
bla
end
Start
bla
bla
MATCH
bla
end
Start
bla
bla
bla
end
您可以'啜饮'该文件,然后测试MATCH
的每个匹配组:
$ echo "$tgt" | perl -0777 -lne 'for (/^Start.*?^end/msg) { print if /^MATCH/m; }'
Start
bla
bla
MATCH
bla
end
也适用于文件。