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