in reply to Re^2: Replace value in the text file
in thread Replace value in the text file

Text::CSV_XS, its slower pure-perl implementation Text::CSV

From the doc of the latter:

Text::CSV is a thin wrapper for Text::CSV_XS-compatible modules now. ... Text::CSV uses Text::CSV_XS by default, and when Text::CSV_XS is not available, falls back on Text::CSV_PP, which is bundled in the same distribution as this module.

Personally, I usually recommend Text::CSV, although I guess I should start telling people to make sure Text::CSV_XS is installed as well :-)

Replies are listed 'Best First'.
Re^4: Replace value in the text file
by afoken (Chancellor) on Jun 30, 2017 at 21:04 UTC
    Text::CSV is a thin wrapper for Text::CSV_XS-compatible modules now.

    Of course, you are right. But one or one and a half decades ago, when I had to handle CSV files from Perl for the first time, Text::CSV was what now is Text::CSV_PP. That's written to my biological persistent storage, and it's damn hard to update. ;-) I know that, because it's not the first time that someone had to remind me.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re^4: Replace value in the text file
by mhoang (Acolyte) on Jun 30, 2017 at 05:43 UTC

    I love to use the one you recommend but I am just a beginner so not sure how to apply See if you can help me to edit my code below I like to change the value in column one to a fix value. Any number should reduced by 1 except "1" becomes "P". I am trying to learn how to use map or grep not creating the hash, that the guys showed me. Thanks Macy

    "Header1","Header2",Header3" "A123","1","valueB1" "B234","1","valueB2" "C345","2","valueB3" "D456","3","valueB4" "E567","4","valueB5" "F678","5","valueB6"

    and the output should be

    "Header1","Header2",Header3" "A123","P","valueB1" "B234","P","valueB2" "C345","1","valueB3" "D456","2","valueB4" "E567","3","valueB5" "F678","4","valueB6"

    here is my code

    open my $fh1,'<',"NRoomch.txt"; my @a = <$fh1>; my @arr; for $i (0..$#a){ my @b = split(/,/,$a[$i]); for $j (0..$#b) { $b[$j] =s~/"//g; if ($j==1 && my @arr = grep { $_ =~ /\"1"$/ } @b); @arr = map{$_ = "P"} @arr; else @arr = map {$b[$j] - 1} (1..$#b); print @arr; }; }; close($fh1);

      Your code does not compile. Please do yourself a huge favor and  use warnings; and  use strict; at the start of every file. This is especially important for a novice Perler.

      Even with strict and warnings, your code still has syntactic problems. The monks like to see working code, even if it does not do all (or even most) of what you want. Please see Short, Self-Contained, Correct Example.

      Some syntactic thoughts:

      • $b[$j] =s~/"//g; What is this statement supposed to do? Will it even compile?
      • if ($j==1 && my @arr = grep { $_ =~ /\"1"$/ } @b); Will this compile?
      • else Will this compile?

      Some best-practices thoughts:

      • my @a = <$fh1>; Is this supposed to read all lines from the file handle? Then why not name the variable  @lines or  @input_lines (since you want to transform them and then produce something like an  @output_lines array) instead?
      • Similar objections apply to array names like  @arr and  @b
      • if ($j==1 && my @arr = grep { $_ =~ /\"1"$/ } @b); Assuming this actually compiled, which  @arr in the script is referred to in the following  @arr = map{$_ = "P"} @arr; statement? (There are two  @arr arrays floating around in the script.)
      • @arr = map {$b[$j] - 1} (1..$#b); A similar  @arr confusion attaches to this statement ...
      • print @arr; ... and to this.

      These comments are dashed off quickly. Although it may seem that way, I don't mean to be blunt or dismissive. I hope you will take them as food for thought.


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

        Thanks for pointing out all the un-proper defined in my code. I will follow your recommendation to improve it.

      Here's a template for using Text::CSV that you can edit based on your needs (you should also install Text::CSV_XS). Note that $row is an arrayref, how to work with it is discussed in perlreftut.

      #!/usr/bin/env perl use warnings; use strict; use Text::CSV; my $csv = Text::CSV->new({ binary=>1, auto_diag=>2, eol=>$/, always_quote=>1 }); open my $ifh, '<', 'NRoomch.txt' or die $!; open my $ofh, '>', 'output.txt' or die $!; while ( my $row = $csv->getline($ifh) ) { $row->[1]='P'; # your logic to modify 2nd column here $csv->print($ofh, $row); } $csv->eof or $csv->error_diag; close $ifh; close $ofh;

        thanks for pointing me to the perlreftut. I love it !

        I follow your method using HTML Table to print output.html but I alway get it printing to screen can you correct for me please?. I have worked out the value for the array. It's worth to spend weekend to learn the perlref

        #!/usr/bin/perl use strict; use warnings; my @values = (); use HTML::Table; my $table = HTML::Table->new( -cols => 3, -border => 1, -padding => 1, -head => [('Header1','Header2','Header3')], ); my $sourceFile = "<C:/Perl-Script/File1.txt"; open my $ifh,$sourceFile or die $!; open my $ofh, '>', 'C:/Perl-Script/output.html' or die $!; while (my $row = <$ifh>) { chomp($row); $row =~ s/"//g; @values = split(',',$row); $table ->addRow(@values); } $table->print ($ofh,@values); close $ifh; close $ofh;
        Nirvana is Now or Never