2013-03-11 4 views
3

Я хотел бы напечатать конкретные данные после сопоставления рисунка или строки. У меня есть файл, как это:Perl: Как напечатать следующую строку после сопоставления рисунка?

#******************************  
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 

#. .  
#. .  
#.  
#.  

Я хочу, чтобы напечатать данные, например, после того, как линии «типа ....» и черточки линии «------», которая является 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";  
}  
}  
}  

Ожидаемый результат:

Car Type   No. 
    N17    bg099 
    A57    ft2233  
    L45    nh669 
    ..    .. 
    .    . 
+0

Ваш вопрос делает матч с description.You сказать печать рядом два lines.and внутри вопрос должен напечатать только одну строку после сопоставляя две строки. – Vijay

ответ

6
while (<FILE>) { #read line by line 
    if ($_ =~ /^Car/) { #if the line starts with 'Car' 
     <FILE> or die "Bad car file format"; #read the first line after a Car line, which is '---', in order to get to the next line 
     my $model = <FILE>; #assign the second line after Car to $model, this is the line we're interested in. 

     $model =~ /^([^\s]+)\s+([^\s]+)/; #no need for if, assuming correct file format #capture the first two words. You can replace [^\s] with \w, but I prefer the first option. 
     print "$1 $2\n"; 
    } 
} 

Или, если вы предпочитаете более компактное решение:

while (<FILE>) { 
    if ($_ =~ /^Car/) { 
     <FILE> or die "Bad car file format"; 
     print join(" ",(<FILE> =~ /(\w+)\s+(\w+)/))."\n"; 
    } 
} 
+1

У меня был почти точно такой же ответ наполовину написанный. – RET

+0

@Mattan - Я применил вашу кодировку, но получаю отличный результат.Это только печатает, 7 9, 7 3, 5 9. Не возражаете ли вы объяснить свое кодирование? Спасибо и оцените. – Zoe

+0

@ Mattan - Он работает! Я получил это сейчас ... Спасибо =) – Zoe

2

Я получил код для работы с парой небольших ухищрений. Это все еще не идеально, но это работает.

  • "while" должно быть в нижнем регистре.
  • Вы никогда не увеличиваете $ i.
  • То, как вы повторно используете @array, сбивает с толку в лучшем случае, но если вы просто вывести $ a, вы получите данные о своем автомобиле.

Код:

$file_to_get = "input_file.txt"; 
open (FILE, $file_to_get) or die $!; 

my @array; 

while (@array = <FILE>) { 
    $i = 0; 

    foreach my $line (@array) { 

     if ($line =~ m/(Car)((.*))/) { 
      my $a = $array[$i+2]; 
      push (@array, $a); 
      print $a; 
     } 

     $i++; 
    } 
} 
close(FILE); 
1
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, вы можете сделать это, как показано ниже:

> awk '/Type/{getline;if($0~/^#---*/){getline;print $1,$2}}' your_file 
N17 bg099 
A57 ft2233 
L45 nh669 
1

оболочки один вкладыш, чтобы сделать то же самое

echo "Car Type   No. "; \ 
    grep -A 2 Type data.txt \ 
    | grep -v -E '(Type|-)' \ 
    | grep -o -E '(\w+ *\w+)' 
4

Вот еще один вариант:

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 

Использование: perl script.pl inFile [>outFile]

Edit: Упрощенный

2

Что-то вроде этого:

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"; 
} 
1

Решение с помощью Perl оператора флип-флоп. Допущение от входа, что вы всегда иметь полную линию в конце блока интереса

cat $your_file | perl -ne '$a=/^#--/;$b=/^Total/;print if(($a .. $b) && !$a && !$b);' 
Смежные вопросы