我需要在A和(B或C)模式之间提取文本,其中包含D模式。
例如我有一个文件,需要在" proc sql"之间提取所有文件。和("退出"或"运行"),包含"索引"内部。
proc sql bla-bla-bla index=10; quit proc sql bla-bla-bla quit; proc sql index=10; run
需要输出:
proc sql bla-bla-bla index=10; quit proc sql index=10; run
到现在为止我有这样的解决方案:
perl -0777 -lne 'print for grep /\bindex\b/i, /^proc sql.*?quit.*?\n/mgs' file
但它只提取" proc sql"和"退出" (不是"退出"或"运行"),包含" index"。我不知道如何添加OR操作。
如果你可以提出替代的awk / sed / grep解决方案 - 会很好。
答案 0 :(得分:0)
这会按照你的要求行事。它累积到$block
开始和结束模式之间的所有行。到达结束模式时,如果它包含index
use strict;
use warnings;
my $block;
while ( <DATA> ) {
my $state = /^proc sql\b/ .. /^(?:quit|run)\b/;
$block .= $_ if $state;
if ( $state =~ /E/ ) {
print $block, "\n" if $block =~ /^index=/m;
$block = '';
}
}
__DATA__
proc sql
bla-bla-bla
index=10;
quit
proc sql
bla-bla-bla
quit;
proc sql
index=10;
run
<强>输出强>
proc sql
bla-bla-bla
index=10;
quit
proc sql
index=10;
run
答案 1 :(得分:0)
鉴于您的输入文件名为input.txt,这将在awk中解决它:
awk 'BEGIN {
procDetected = 0;
indexDetected = 0;
}
/proc/ {
buffer = "";
indexDetected = 0;
procDetected = 1;
}
/index/ {
indexDetected = 1;
}
{
if (procDetected) {
# Add the line to the buffer.
buffer = buffer $0 "\n";
}
}
/run/ || /quit/ {
if (procDetected && indexDetected) {
print buffer;
}
procDetected = 0;
indexDetected = 0;
}' input.txt