我正在尝试将两个模式之间的多行合并为由空格分隔的一行。但是,我需要保留这两个模式之前和之后的文本。
Input
Line 1
Line 2
Line 3
PATTERN 1
Line 4
Line 5
Line 6
PATTERN 2
Line 7
Line 8
Desired Output:
Line 1
Line 2
Line 3
Line 4 Line 5 Line 6
Line 7
Line 8
我发现了许多使用sed、awk和perl组合多行的示例,但是我找不到一个示例来说明如何在模式匹配前后保持文本不变。谢谢。
发布于 2020-11-19 11:15:45
这取决于你是如何在行中阅读的。如果你给我更多关于你想做什么的信息,我可以给你一个更好的答案。
如果你一次只读一个,这就足够了。
while (my $line = <HANDLE>) {
if ($line =~ m/PATTERN1/) {
my @collection;
while (my $inner = <HANDLE>) {
if ($inner =~ m/PATTERN2/) {
last;
}
else {
push @collection, $inner;
}
}
chomp @collection;
print "@collection\n";
}
else { print $line; }
}
如果您将所有内容都放在一个字符串中,并且想要就地替换它,请使用此正则表达式。
$text =~ s{^PATTERN1$(.*?)^PATTERN2$}{ my $t = $1; $t =~ tr/\n/ /; $t; }smg;
谢谢。
发布于 2020-11-19 18:29:50
这在很大程度上是Perl的“触发器”操作符的作用。
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my @collect;
while (<DATA>) {
chomp;
# If we're between our markers...
if (/^PATTERN 1/ .. /^PATTERN 2/) {
# At the start marker, empty the array
if (/^PATTERN 1/) {
@collect = ();
# At the end marker, print the array
} elsif (/^PATTERN 2/) {
say join ' ', @collect;
# Otherwise, push the line onto the array
} else {
push @collect, $_;
}
# Otherwise, just print the line
} else {
say;
}
}
__DATA__
Line 1
Line 2
Line 3
PATTERN 1
Line 4
Line 5
Line 6
PATTERN 2
Line 7
Line 8
为了便于开发,我在这里从DATA
文件句柄中读取。您需要将其更改为已打开的某个文件句柄。
https://stackoverflow.com/questions/64904646
复制相似问题