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

Hello everyone, I am trying to replace whitespaces, from my input file, with commas. The challenge I am currently experiencing is that when a selection of the line has no characters it is not recognizing the selection therefore not adding the extra comma in place of the line. What I want my script to do is, add the comma regardless if there is or isn't characters present in the section of the line. Below is what I currently have, where I'm stating that every 3 whitespaces in my input file per line, replace with a comma. Thank you for your time and help, as always everyone is very helpful on here.

use strict; use warnings; open (NEW, ">", "OUTPUT_COMMA.txt" ) or die "could not open:$!"; open (FILE, "<", "INPUT.txt") or die "could not open:$!"; while (my $line = <FILE>) { $line =~s/\s{3} +/,/g; print NEW $line; } close (FILE); close (NEW)

INPUT File:

12345 DOE,JOHN $50.00 REFUND COMPLETE 12345 DOE,JOHN $25.00 DENIED COMPLETE 12345 DOE,JOHN $75.00 COMPLETE 12345 DOE,JOHN $10.00 REFUND COMPLETE

EXPECTED OUTPUT File:

12345,DOE,JOHN,$50.00,REFUND,COMPLETE 12345,DOE,JOHN,$25.00,DENIED,COMPLETE 12345,DOE,JOHN,$75.00,,COMPLETE 12345,DOE,JOHN,$10.00,REFUND,COMPLETE

CURRENT OUTPUT File:

12345,DOE,JOHN,$50.00,REFUND,COMPLETE 12345,DOE,JOHN,$25.00,DENIED,COMPLETE 12345,DOE,JOHN,$75.00,COMPLETE 12345,DOE,JOHN,$10.00,REFUND,COMPLETE

Replies are listed 'Best First'.
Re: Replace Whitespace with Comma
by toolic (Bishop) on Aug 16, 2016 at 19:41 UTC
    It looks like your input is fixed-width. If so, use unpack and join:
    use warnings; use strict; while (<DATA>) { my @cols = unpack 'A8A11A9A9A*', $_; print join(',', @cols), "\n"; } __DATA__ 12345 DOE,JOHN $50.00 REFUND COMPLETE 12345 DOE,JOHN $25.00 DENIED COMPLETE 12345 DOE,JOHN $75.00 COMPLETE 12345 DOE,JOHN $10.00 REFUND COMPLETE
Re: Replace Whitespace with Comma
by GrandFather (Saint) on Aug 16, 2016 at 20:44 UTC

    You appear to be creating a CSV file. On the face of it your output line should be:

    12345,"DOE,JOHN",$50.00,REFUND,COMPLETE

    to preserve the sense of the input file where DOE,JOHN is a single field. You should seriously consider using Text::CSV to generate the output file. It will look after correct quoting and various other possible issues for you.

    Premature optimization is the root of all job security
Re: Replace Whitespace with Comma
by Marshall (Canon) on Aug 16, 2016 at 20:46 UTC
    The Anon Monk solution is certainly something to consider. (update added: I see problems if this name field is way longer than your example. I suspect fixed column will wind up be the "way to go").

    If you are making a .CSV file, then I think you will need to quote column 2, the name column. "DOE,JOHN" because with names, there could be titles, "DOE,JOHN,JR.", "DOE,JOHN,III", or other kinds of weirdness involving multiple commas which would throw off the parsing of the comma separated file. I would as a minor suggestion, skip blank lines on the input (sometimes these files wind up with a blank line at the end which is hard to see because it is invisible).

    Anyway, one way below. I did add a test case where more than one field is missing.

    #!/usr/bin/perl use strict; use warnings; while(<DATA>) { next if /^\s*$/; #skip blank lines s/^(\d+\s+)(\S+)(.+)/$1"$2"$3/; #quote column 2 s/\s{3,7}/,/g; print; } =prints: 12345,"DOE,JOHN",$50.00,REFUND,COMPLETE 12345,"DOE,JOHN",$25.00,DENIED,COMPLETE 12345,"DOE,JOHN",$75.00,,COMPLETE 12345,"DOE,JOHN",$10.00,REFUND,COMPLETE 12345,"DOE,JOHN",,,INCOMPLETE =cut __DATA__ 12345 DOE,JOHN $50.00 REFUND COMPLETE 12345 DOE,JOHN $25.00 DENIED COMPLETE 12345 DOE,JOHN $75.00 COMPLETE 12345 DOE,JOHN $10.00 REFUND COMPLETE 12345 DOE,JOHN INCOMPLETE
    Update: as an extra thought, when I have a choice of separator character on these types of files, I usually choose "|" instead of "," - that is valid "CSV" and can be read by Excel. It is just easier to parse since there is no confusion about column separator vs embedded comma in quotes. A number of DB exported files that I work with come this way and its is a bit easier to fiddle with. However there are some excellent modules to parse "real" CSV - that parsing job way to complicated to try on your own.
Re: Replace Whitespace with Comma
by choroba (Cardinal) on Aug 16, 2016 at 20:34 UTC
    TIMTOWTDI: You can also use unpack to process fixed width input.
    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; while (<>) { my @fields = unpack 'A8A11A9A9A8'; say join ',', @fields; }

    ($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,
Re: Replace Whitespace with Comma
by Anonymous Monk on Aug 16, 2016 at 19:46 UTC
    #!/usr/bin/perl # http://perlmonks.org/?node_id=1169858 use strict; use warnings; while(<DATA>) { s/\s{3,7}/,/g; print; } __DATA__ 12345 DOE,JOHN $50.00 REFUND COMPLETE 12345 DOE,JOHN $25.00 DENIED COMPLETE 12345 DOE,JOHN $75.00 COMPLETE 12345 DOE,JOHN $10.00 REFUND COMPLETE