tags:

views:

445

answers:

4

I have a CSV file that was extracted from a ticketing system (I have no direct DB access to) and need to append a couple of columns to this from another database before creating reports off of it in Excel.

I'm using Perl to pull data out of the other database and would like to just append the additional columns to the end of each line as I process the file.

Is there a way to do this without having to basically create a new file? The basic structure is:

foreach $line (@lines) {
    my ($vars here....) = split (',',$line);
    ## get additional fields
    ## append new column data to line
}
A: 

Consider using the -i option to edit <> files in-place.

laalto
+7  A: 

You could look at DBD::CSV to treat the file as if it were a database (which would also handle escaping special characters for you).

David Dorward
+3  A: 

You can use Tie::File (in the Perl core since Perl 5.8) to modify a file in place:

#!/usr/bin/perl

use strict;
use warnings;

use Tie::File;


my $file = shift;

tie my @lines, "Tie::File", $file
    or die "could not open $file: $!\n";

for my $line (@lines) {
    $line .= join ",", '', get_data();
}

sub get_data {
    my $data = <DATA>;
    chomp $data;
    return split /-/, $data
}

__DATA__
1-2-3-4
5-6-7-8

You can also use in-place-editing with the @ARGV/<> trick by setting $^I:

#!/usr/bin/perl

use strict;
use warnings;

$^I = ".bak";

while (my $line = <>) {
    chomp $line;
    $line .= join ",", '', get_data();
    print "$line\n";
}

sub get_data {
    my $data = <DATA>;
    chomp $data;
    return split /-/, $data
}

__DATA__
1-2-3-4
5-6-7-8
Chas. Owens
The second option works for me, less libraries to download, etc. Also eliminated about 10 lines from my code.
MattS
Tie::File has been a part of Core Perl since 5.8 (well 5.7.3, but that was a dev release).
Chas. Owens
Note that these work as long as none of the fields in the record can have vertical whitespace. That sounds stupid, but if you play with CSV long enough you'll eventually run into someone doing that. :)
brian d foy
+1  A: 

Despite any nice interfaces, you have to eventually read the file line-by-line. You might even have to do more that that if some quoted fields can have embedded newlines. Use something that knows about CSV to avoid some of those problems. Text::CSV_XS should save you most of the hassle of odd cases.

brian d foy