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

Hi,

I have a csv file of which data is as below:

A,,D,E,F L,T,,G,Q C,D,E,,L

How can i insert "null" in this file whenever a blank column(,,) comes.

Expected Output

A,NULL,D,E,F L,T,NULL,G,Q C,D,E,NULL,L

Replies are listed 'Best First'.
Re: insert null in missing places of csv
by choroba (Cardinal) on Feb 19, 2016 at 11:21 UTC
    To process CSV, use the Text::CSV_XS module (I guess your CSV is a bit more complicated than shown in the example). Read the input line by line, replace each zero-length entry with the "NULL" string.

    #!/usr/bin/perl use warnings; use strict; use Text::CSV_XS; my $csv = 'Text::CSV_XS'->new({binary => 1}); open my $CSV, '<', shift or die $!; while (my $row = $csv->getline($CSV)) { $csv->say(\*STDOUT, [ map length ? $_ : 'NULL', @$row ]); }
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Note that this approch changes both 1,2,,3,4 and 1,2,"",3,4 to 1,2,NULL,3,4.

      The safe way would be

      $ cat test.pl use 5.18.2; use warnings; use Text::CSV_XS qw( csv ); csv (in => csv ( in => *ARGV, blank_is_undef => 1, on_in => sub { $_ //= "NULL" for @{$_[1]}; }, ), ); $ cat test.csv 1,2,,3,4 1,2,"",3,4 $ perl test.pl test.csv 1,2,NULL,3,4 1,2,,3,4

      Enjoy, Have FUN! H.Merijn

        awesome

        this meets my requirement, all other suggestions are even replacing 0 with NULL.

        Could you please suggest me how can i call csv file directly inside the script instead of calling it on command prompt ?

        This is what I am running using your input:

        #!/usr/bin/perl #use strict; use warnings; use Text::CSV_XS qw( csv); csv (in => csv ( in => *ARGV, blank_is_undef => 1, on_in => sub { $_ //= "NULL" for @{$_[1]}; }, ), );
        perl test.pl 1.csv

        all i need is to call 1.csv inside test.pl only

        perl test.pl
Re: insert null in missing places of csv
by Discipulus (Canon) on Feb 19, 2016 at 11:18 UTC
    Hello ukhare

    what have you tried so far? I'm not a csv expert but you can do for sure something similar to:

    @current_row = map { $_ ? $_ : qq(NULL) } @current_row

    you can also do the job in a oneliner

    perl -lanF',' -e "print join',',map {$_ ? $_ : 'NULL'} @F " testcsvnul +l.txt A,NULL,D,E,F L,T,NULL,G,Q C,D,E,NULL,L

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      NOT WORKING :

      <$ perl -lanF',' -e "print join',',map {$_ ? $_ : 'NULL'} @F " 1.txt Bareword found where operator expected at -e line 1, near "1.txt" (Missing operator before txt?) Bareword found where operator expected at -e line 1, near "1.txt" (Missing operator before txt?) syntax error at -e line 1, near "1.txt " Execution of -e aborted due to compilation errors.

        My impression is that Discipulus's
            perl -lanF',' -e "print join',',map {$_ ? $_ : 'NULL'} @F " testcsvnull.txt
        is running under Windoze, and your
            <$ perl -lanF',' -e "print join',',map {$_ ? $_ : 'NULL'} @F " 1.txt
        is running under *nix. Fix the quoting as appropriate to your OS shell and give it another try.


        Give a man a fish:  <%-{-{-{-<

Re: insert null in missing places of csv
by AnomalousMonk (Archbishop) on Feb 19, 2016 at 16:19 UTC

    I think the advice of choroba and Tux to base your solution on Text::CSV is well taken. But I'm a hopeless regex junky, so here's that approach (requires Perl verion 5.10 or greater):

    c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; my @records = ( ',P,Q,R,S', 'A,,D,E,F', 'L,T,,G,Q', 'C,D,E,,L', 'V,W,X,Y,', ' , , , ,', ',,,,', ',', ' , ', '', ' ', ); ;; for my $rec (@records) { print qq{'$rec'}; $rec =~ s{ (?: \A | ,) \K \s* (?= ,) | (?<= ,) \s* (?= , | \z) | \A \s* \z }{NULL}xmsg; print qq{'$rec' \n}; } " ',P,Q,R,S' 'NULL,P,Q,R,S' 'A,,D,E,F' 'A,NULL,D,E,F' 'L,T,,G,Q' 'L,T,NULL,G,Q' 'C,D,E,,L' 'C,D,E,NULL,L' 'V,W,X,Y,' 'V,W,X,Y,NULL' ' , , , ,' 'NULL,NULL,NULL,NULL,NULL' ',,,,' 'NULL,NULL,NULL,NULL,NULL' ',' 'NULL,NULL' ' , ' 'NULL,NULL' '' 'NULL' ' ' 'NULL'
    The only problematic case is the  '' or  ' ' empty/blank string, but if you don't like how that's handled, it's easy to take the  \A \s* \z term out of the alternation or change it.


    Give a man a fish:  <%-{-{-{-<