3

模様や線を合わせて特定のデータを印刷したい。次のようなファイルがあります。

#******************************    
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";      
}      
}    
}    

期待される出力:

Car Type            No.  
   N17             bg099  
   A57             ft2233    
   L45             nh669  
   ..              ..  
   .               . 
4

7 に答える 7

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";
    } 
} 
于 2013-03-11T05:58:16.707 に答える
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]

編集:簡略化

于 2013-03-11T06:23:13.383 に答える
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);
于 2013-03-11T05:57:21.987 に答える
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";
}
于 2013-03-11T09:50:05.103 に答える
1

同じことをするためのシェルワンライナー

echo "Car Type            No.  "; \
    grep -A 2 Type data.txt \
    | grep -v -E '(Type|-)' \
    | grep -o -E '(\w+ *\w+)'
于 2013-03-11T06:19:32.490 に答える
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
于 2013-03-11T05:59:22.917 に答える
1

Perl フリップフロップ演算子を使用したソリューション。対象のブロックの最後に常に合計行があるという入力からの仮定

perl -ne '$a=/^#--/;$b=/^Total/;print if(($a .. $b) && !$a && !$b);' file
于 2015-09-28T22:19:38.807 に答える