[wellylug] curly csv formatting
Grant McLean
grant at mclean.net.nz
Fri Jul 9 13:24:13 NZST 2004
> the csv layout is now as follows:
>
> surname,firstname(s),date of birth, 1st qualification, various details
> , , , , 2nd qualification, various details
> , , , , 3rd qualification, various details
> , , , , 4th qualification, various details
> ..and so one until it gets to the next new client..
Are the empty fields really filled with spaces? If not, here's a one-liner:
perl -n -F, -a -e '$F[$_] ||= $t[$_] foreach (0..2); print join(",", @F);
$t[$_] = $F[$_] foreach (0..2)' filename.csv
The -n means loop through each line in the named file.
The -F, -a means split each line on commas and store the fields in the
global array @F
Pulling apart the code in the -e ...
$F[$_] ||= $t[$_] foreach (0..2)
This line introduces a temporary array @t (which will initially be empty)
and uses the ||= operator to copy the value from $t[n] to $F[n] for each of
the first three element if the current value in $F[n] is 'false' (ie: empty,
undefined or 0).
If you really do have spaces in the empty fields then spaces are not false
so you'd need to do something like this:
foreach (0..2) { $F[$_] = $t[$_] unless $F[$_] =~ /\S/ }
Which only does the assignment if $F[n] does not contain a non-whitespace
character (sorry about the double negative)
print join(",", @F);
This line reassembles the fields into a line and prints it out (the trailing
newline stayed attached to the last element in @F).
$t[$_] = $F[$_] foreach (0..2)
This line unconditionally copies the first three elements from @F to @t.
It might look clearer as a script than a one-liner:
#!/usr/bin/perl -w
use strict;
my(@F, @t);
while(<>) {
@F = split /,/;
foreach (0..2) { $F[$_] = $t[$_] unless $F[$_] =~ /\S/ }
print join ",", @F;
$t[$_] = $F[$_] foreach (0..2);
}
Cheers
Grant
More information about the wellylug
mailing list