[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