Why after the while loop I am only getting last row value?

后端 未结 3 664
南旧
南旧 2021-01-23 22:42

This is the files I am reading,

#Log1
Time    Src_id  Des_id  Address
0   34  56  x9870
2   36  58  x9872
4   38  60  x9874
6   40  62  x9876
8   42  64  x9878
         


        
3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-23 23:24

    Following code demonstrates how to read and print log files (OP does not specify why he splits lines into fields)

    use strict;
    use warnings;
    use feature 'say';
    
    my $fname1  = 'log1.txt';
    my $fname2  = 'log2.txt';
    my $div     = "\t";
    
    my $file1   = read_file($fname1);
    my $file2   = read_file($fname2);
    
    print_file($file1,$div);
    print_file($file2,$div);
    
    sub read_file {
        my $fname = shift;
        
        my @data;
        
        open my $fh, '<', $fname
            or die "Couldn't read $fname";
            
        while( <$fh> ) {
            chomp;
            next if /^#Log/;
            push @data, [split];
        }
            
        close $fh;
        
        return \@data;
    }
    
    sub print_file {
        my $data = shift;
        my $div  = shift;
        
        say join($div,@{$_}) for @{$data};
    }
    

    Output

    Time    Src_id  Des_id  Address
    0       34      56      x9870
    2       36      58      x9872
    4       38      60      x9874
    6       40      62      x9876
    8       42      64      x9878
    Time    Src_id  Des_id  Address
    1       35      57      x9871
    3       37      59      x9873
    5       39      61      x9875
    7       41      63      x9877
    9       43      65      x9879
    

    Let's assume that OP wants to merge two files into one with sorted lines on Time field

    • read files into %data hash with Time field as key
    • print header (@fields)
    • print hash values sorted on Time key
    use strict;
    use warnings;
    use feature 'say';
    
    my(@fields,%data);
    
    my $fname1  = 'log1.txt';
    my $fname2  = 'log2.txt';
    
    read_data($fname1);
    read_data($fname2);
    
    say join("\t",@fields);
    say join("\t",@{$data{$_}}) for sort { $a <=> $b } keys %data;
    
    sub read_data {
        my $fname = shift;
        
        open my $fh, '<', $fname
            or die "Couldn't open $fname";
            
        while( <$fh> ) {
            next if /^#Log/;
            if( /^Time/ ) {
                @fields = split;
            } else {
                my @line = split;
                $data{$line[0]} = \@line;
            }
        }
            
        close $fh;
    }
    

    Output

    Time    Src_id  Des_id  Address
    0       34      56      x9870
    1       35      57      x9871
    2       36      58      x9872
    3       37      59      x9873
    4       38      60      x9874
    5       39      61      x9875
    6       40      62      x9876
    7       41      63      x9877
    8       42      64      x9878
    9       43      65      x9879
    

提交回复
热议问题