Perl:如何在匹配模式后打印下一行?

Perl:如何在匹配模式后打印下一行?,perl,pattern-matching,Perl,Pattern Matching,我想在匹配图案或线条后打印特定数据。我有这样一个文件: #****************************** List : car Design: S Date: Sun 10:10 #****************************** b-black g-green r-red Car Type No. color #--------------------------------------

我想在匹配图案或线条后打印特定数据。我有这样一个文件:

#******************************    
List : car  
Design: S  
Date: Sun 10:10  
#******************************

b-black  
g-green
r-red  

Car Type              No.           color  
#-------------------------------------------    
N17              bg099            g  
#-------------------------------------------    
Total 1 car  

#****************************** 
List : car  
Design: L  
Date: Sun 10:20  
#******************************

b-black  
g-green
r-red  

Car Type            No.            color   
#-------------------------------------------    
A57            ft2233            b  
#-------------------------------------------    
Total 1 car  

#******************************    
List : car  
Design: M  
Date: Sun 12:10  
#******************************    

b-black  
g-green
r-red  

Car Type           No.             color  
#-------------------------------------------    
L45            nh669             g   
#-------------------------------------------    
Total 1 car  

#. .    
#. .     
#.    
#.    
我想打印数据,例如在“Type…”行和虚线“----”行之后,即N17和bg099。我已经试过了,但不起作用

my @array;    

While (@array = <FILE>) {    

foreach my $line (@array) {    

if ($line =~ m/(Car)((.*))/) {      

my $a = $array[$i+2];    
push (@array, $a);    
}  

if ($array[$i+2] =~ m/(.*)\s+(.*)\s+(.*)/) {    
my $car_type = "$1";      
print "$car_type\n";      
}      
}    
}    

我对你的代码做了一些小的调整。 它仍然不完美,但它可以工作

  • “while”应该是小写
  • 你从不增加$i
  • 重复使用@array的方式充其量是令人困惑的,但如果您只输出$a,您将获得您的汽车数据
代码:

$file\u to\u get=“input\u file.txt”;
打开(文件,$FILE\u to\u get)或死亡$!;
我的@数组;
而(@array=){
$i=0;
foreach my$行(@array){
如果($line=~m/(车)(.*)/){
我的$a=$array[$i+2];
推送(@array,$a);
打印$a;
}
$i++;
}
}
关闭(文件);
while(){#逐行阅读
如果($){如果行以“Car”开头
或者死在“坏的汽车文件格式”#读取汽车行后的第一行,即“---”,以便进入下一行
my$model=#将Car后面的第二行指定给$model,这是我们感兴趣的行。
$model=~/^([^\s]+)\s+([^\s]+)/;#不需要if,假设文件格式正确#捕获前两个单词。您可以将[^\s]替换为\w,但我更喜欢第一个选项。
打印“$1$2\n”;
}
}
或者,如果您喜欢更紧凑的解决方案:

while (<FILE>) { 
    if ($_ =~ /^Car/) { 
        <FILE> or die "Bad car file format"; 
        print join(" ",(<FILE> =~ /(\w+)\s+(\w+)/))."\n";
    } 
} 
while(){
如果($\=~/^Car/){
或死“坏车文件格式”;
打印联接(“,(=~/(\w+)\s+(\w+/))。“\n”;
} 
} 

a外壳一个衬里做同样的事情

echo“车型号”\
grep-A 2 Type data.txt\
|grep-v-E'(类型|-)'\
|grep-o-E'(\w+*\w+)
这里是另一个选项:

use strict;
use warnings;

print "Car Type\tNo.\n";

while (<>) {
    if (/#-{32}/) {
        print "$1\t$2\n" if <> =~ /(\S+)\s+(\S+)/;
        <>;
    }
}
用法:
perlscript.pl infle[>outFile]

编辑:简化的

类似这样的内容:

while (my $line = <>) {
    next unless $line =~ /Car\s+Type/;
    next unless $line = <> and $line =~ /^#----/;
    next unless $line = <>;
    my @fields = split ' ', $line;
    print "@fields[0,1]\n";
}
while(我的$line=){
下一步除非$line=~/Car\s+Type/;
下一步,除非$line=和$line=~/^#----/;
下一步,除非$line=;
我的@fields=拆分“”,$line;
打印“@fields[0,1]\n”;
}

使用Perl触发器运算符的解决方案。根据输入的假设,您总是在感兴趣的块的末尾有一个合计行

perl -ne '$a=/^#--/;$b=/^Total/;print if(($a .. $b) && !$a && !$b);' file

我的答案几乎完全一样。@Mattan-我应用了你的编码,但得到了不同的结果。它只打印,79,73,59。你介意解释一下你的编码吗?谢谢,非常感谢。我修复了代码(将加号放在捕获表达式内部的第二个正则表达式中,而不是它的外部)。我还添加了注释。你的问题与你的描述相符。你说打印下两行。在问题内部,匹配两行后只需打印一行。
perl -lne 'if(/Type/){$a=<>;$a=<>;$a=~m/^([^\s]*)\s*([^\s]*)\s/g; print $1." ".$2}' your_file
> perl -lne 'if(/Type/){$a=<>;$a=<>;$a=~m/^([^\s]*)\s*([^\s]*)\s/g; print $1." ".$2}' temp
N17 bg099
A57 ft2233
L45 nh669
> awk '/Type/{getline;if($0~/^#---*/){getline;print $1,$2}}' your_file
N17 bg099
A57 ft2233
L45 nh669
use strict;
use warnings;

print "Car Type\tNo.\n";

while (<>) {
    if (/#-{32}/) {
        print "$1\t$2\n" if <> =~ /(\S+)\s+(\S+)/;
        <>;
    }
}
Car Type    No.
N17 bg099
A57 ft2233
L45 nh669
while (my $line = <>) {
    next unless $line =~ /Car\s+Type/;
    next unless $line = <> and $line =~ /^#----/;
    next unless $line = <>;
    my @fields = split ' ', $line;
    print "@fields[0,1]\n";
}
perl -ne '$a=/^#--/;$b=/^Total/;print if(($a .. $b) && !$a && !$b);' file