[wellylug] curly csv formatting
Mark Signal
mark at databackup.co.nz
Fri Jul 9 17:08:08 NZST 2004
do you have any idea at all how much time and agony you just saved me????
I will be able to continue the illusion of competence with the customer (its
all a matter of relative ignorance)
and thank you to David Antliff - I started researching your answer but I
could see it being a long weekend
thank you guys - I hope that one day I can return the favour.
cheers
Mark Signal
-----Original Message-----
From: wellylug-admin at lists.naos.co.nz
[mailto:wellylug-admin at lists.naos.co.nz]On Behalf Of Grant McLean
Sent: Friday, 9 July 2004 1:24 p.m.
To: wellylug at lists.naos.co.nz
Subject: Re: [wellylug] curly csv formatting
> 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
--
Wellington Linux Users Group Mailing List: wellylug at lists.naos.co.nz
To Leave: http://lists.naos.co.nz/mailman/listinfo/wellylug
---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.712 / Virus Database: 468 - Release Date: 27/06/2004
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.712 / Virus Database: 468 - Release Date: 27/06/2004
More information about the wellylug
mailing list