Transposing CSV data in Perl

后端 未结 2 699
臣服心动
臣服心动 2020-12-21 06:42

I am a Perl beginner and currently working on a Perl script to automate some of our tasks. One script that I\'m working on involves extracting performance data from our syst

2条回答
  •  余生分开走
    2020-12-21 07:18

    Here is my Perl program to transpose row data into columns. A row starts with the headline name followed by one or more values. In my case I needed to remove the date (mm/dd/yyyy) from the headlines so the remainder of the headline field would be unique across multiple rows.

    sub usage { << "EOF";
    
    Convert rows to columns.
    Remove dates from column headings. 
    
    Usage:
        perl $0
    Example:
       $0 data-to-transpose.txt
    
    Source data:
        header1, row1Value1, row2Value2
        header2, row2Value1
        header3 11/31/2011, row3Value1, row3Value2
    Output:
        header1, header2, header3
        row1Value1, row2Value1, row3Value1
        row1Value2, , row3Value2
    
    EOF
    }
    #
    #-------------------------------------------------------------------------------
    
    use 5.010;
    use strict;
    use warnings;
    
    # use Data::Dumper;
    sub printColumns;
    
    my $inFile = shift or die usage();
    # @ARGV = ('.') unless @ARGV;
    
    my @headers;        # Order list of column headers
    my %data;           # map{colHeader, arrayColSourceData }
    my $colCnt = 0;     # maximum number of columns in source data, header, value1, value2, ....
    my $printColHeaders = 1;
    
    my %hasharray; open (my $fh, "<", $inFile) or die "can't open the $inFile";
    while (<$fh>) {
        chomp;
        my @parts = split /,/; 
    
        if (@parts > 1) {
            # Remove date from heading field
            (my $header = $parts[0]) =~ s/[0-9]+\/[0-9]+\/[0-9]+//;
    
            if (!exists $data{$header}) {
               push @headers, $header;
            }
    
            my $have = $data{$header};
            if (defined $data{$header}) {
                if ($printColHeaders == 1) {
                    $printColHeaders = 0;
                    foreach my $col (@headers) {
                        print "$col,";
                    }
                    print "\n";
                }
    
                printColumns();
    
                foreach my $col (@headers) {
                     $data{$col} = undef;
                }
            } 
    
            $data{$header} = \@parts;
            $colCnt = (@parts > $colCnt) ? @parts : $colCnt;
        }
    } 
    
    printColumns();
    print "\n";
    
    foreach my $col (@headers) {
        print "$col,";
    }
    print "\n";
    
    #### Subs 
    sub printColumns() {
        for my $row (1 .. $colCnt-1) {
            foreach my $colHeader (@headers) {
                my $colData = $data{$colHeader};
                if (defined $colData) {
                    my $len=@$colData;
                    if (defined $colData && $row < @$colData) {
                        print "$colData->[$row], ";
                    } else {
                        print ", ";
                    }
                } else {
                    print ", ";
                }
            }
            print "\n";
        } 
    }
    

提交回复
热议问题