Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Good day monks

I have a csv file which looks like

100.1,A ,25, 36,56,89,45,36,56

25.1 ,B,232,565,65,56,56,48,25

103.1,C,25,5,6,9,4,5,56,889,9

10.1,D,5,6,5,8,9,8,12,23,36,6 and so on

so I have a pre defined order of test numbers given by user say the order is 10.1,100.1,25.1,103.1 (see column 1) , then my csv should get arranged as

10.1,D,5,6,5,8,9,8,12,23,36,6

100.1,A ,25, 36,56,89,45,36,56

25.1 ,B,232,565,65,56,56,48,25

103.1,C,25,5,6,9,4,5,56,889,9

hence the content remained the same , only the order changed in csv file . how can I do it

Replies are listed 'Best First'.
Re: arranging the csv file
by Loops (Curate) on Jul 24, 2013 at 04:14 UTC

    Probably should use Text::CSV to parse the data, but in this case cheating isn't too bad:

    use strict; use warnings; my %data; map {$data{0+$_ =~ s/[ ,].*\n?//r} = $_} <DATA>; print $data{0+$_} for qw( 10.1 100.1 25.1 103.1 ); __DATA__ 100.1,A ,25, 36,56,89,45,36,56 25.1 ,B,232,565,65,56,56,48,25 103.1,C,25,5,6,9,4,5,56,889,9 10.1,D,5,6,5,8,9,8,12,23,36,6

    You'd still have to account for duplicate entries and such

      Hi Loops,
      Nice concept of solution, but you are "throwing" away the return values of the map function, so really, I wouldn't build my hash data like this. Moreover, this method is throwing a warnings Argument "\n" isn't numeric in addition ...
      I would rather do like so:

      use strict; use warnings; my %data; while(<DATA>){ my ($key,$value) = split/\s+|,/=>$_,2; $data{$key} = $value; } print $_,',',$data{0+$_},$/ for qw( 10.1 100.1 25.1 103.1 ); __DATA__ 100.1,A ,25, 36,56,89,45,36,56 25.1 ,B,232,565,65,56,56,48,25 103.1,C,25,5,6,9,4,5,56,889,9 10.1,D,5,6,5,8,9,8,12,23,36,6

      If you tell me, I'll forget.
      If you show me, I'll remember.
      if you involve me, I'll understand.
      --- Author unknown to me

        Marrying your and Loops' approach:

        use strict; use warnings; my %data = map { /(.*?)\s*,/ => $_ } <DATA>; print @data{ qw( 10.1 100.1 25.1 103.1 ) }; __DATA__ 100.1,A ,25, 36,56,89,45,36,56 25.1 ,B,232,565,65,56,56,48,25 103.1,C,25,5,6,9,4,5,56,889,9 10.1,D,5,6,5,8,9,8,12,23,36,6

        Question: can anyone do this as a oneliner without a named hash?

Re: arranging the csv file
by 2teez (Vicar) on Jul 24, 2013 at 06:37 UTC

    Since it is a CSV file you could use Text::CSV like Loops mentioned or use Text::CSV_XS like so:

    use strict; use warnings; use Text::CSV_XS; use Data::Dumper; my %data; my $csv = Text::CSV_XS->new( { binary => 1 } ) or die "Cannot use CSV: " . Text::CSV->error_diag(); while ( my $row = $csv->getline(*DATA ) ) { $data{ shift @{$row} } = $row; } $csv->eof or $csv->error_diag(); # Please print out your data as you # specified as you wanted :) print Dumper \%data; __DATA__ 100.1,A ,25, 36,56,89,45,36,56 25.1,B,232,565,65,56,56,48,25 103.1,C,25,5,6,9,4,5,56,889,9 10.1,D,5,6,5,8,9,8,12,23,36,6
    NOTE:
    Am only showing the usage of Text::CSV_XS, here, with "__DATA__", the OP would have to check the documentation to see how it used with a "file".
    The desired print out is also left out for the OP.

    Hope this helps.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
Re: arranging the csv file
by mtmcc (Hermit) on Jul 24, 2013 at 06:26 UTC
    Something like this could work:

    #!/usr/bin/perl use strict; use warnings; my $inputFile = $ARGV[0]; my @userOrder = ("10.1", "100.1", "25.1", "103.1"); my %data; my @line; open (my $data, "<", $inputFile); while (<$data>) { @line = split(",", $_); $line[0] =~ s/ //g; $data{$line[0]} = $_; } for (my $x = 0; $x < @userOrder; $x += 1) { print STDERR " $data{$userOrder[$x]}"; }

Re: arranging the csv file
by Anonymous Monk on Jul 24, 2013 at 04:00 UTC

    how can I do it

    hire a programmer to write a program for you