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

Hello everyone, I am trying to convert my file into a comma delimited file but I am having trouble with the unpack and print. I have set my fields and set my unpack field characters, but when I run the process I get no results. Any help would be great.

use strict; use warnings; open (NEW, ">", "WK_OUTPUT_TEST.txt" ) or die "could not open:$!"; open (FILE, "<", "WK_OUTPUT.txt") or die "could not open:$!"; while (<FILE>) { $line = $_; $line .= ‘ ‘ x (280 – length($line)); #single space between th +e ‘ ‘ ($acct, $name, $ddte, $amt1, $amt2, #amt3, $can, $note, $ndte, + $bar, $ins) = unpack(‘A10A50A8A10A10A10A8A30A8A8A8’, $line); Print NEW “\"$acct\",”; Print NEW “\”$name\”,”; Print NEW “$ddte,”; Print NEW “$amt1,”; Print NEW “$amt2,”; Print NEW “$amt3,”; Print NEW “\"$can\”,”; Print NEW “\"$note\”,”; Print NEW “$ndte,”; Print NEW “\"$bar\”,”; Print NEW “\"$ins\”,”; Print NEW "\n"; } close (FILE); close (NEW)

INPUT FILE:

A123456789 DOE, JANE + 08/10/16 319.25 23.00 54.27 + CLMPD Claim paid correctly +per 08/15/17 BAR.ID HMO + A123456789 DOE, JANE + 08/10/16 23.00 54.27 + CLMPD + 08/15/17 + BAR.ID HMO A123456789 DOE, JANE + 08/10/16 319.25 54.27 + CLMPD Contract Calculation- + 08/15/17 BAR.ID

EXPECTED OUTPUT:

A123456785 “,” DOE, JANE “,” 08/10/16 ”,” 319.25 ”,” 23.00 "," 54.27 ” +,” CLMPD ”,” Claim paid correctly per ”,” 08/15/17 ”,” BAR.ID ”, +” HMO A123456786 “,” DOE, JANE “,” 08/10/16 ”,” ”,” 23.00 "," 54.27 ” +,” CLMPD ”,” ”,” 08 +/15/17 ”,” BAR.ID ”,” HMO A123456787 “,” DOE, JANE “,”08/10/16 ”,” 319.25 ”,” "," 54.27 ” +,” CLMPD ”,” Contract Calculation- ”,” 08/15/17 ”,” BAR.ID +”,” PPO

Replies are listed 'Best First'.
Re: Unpack and Print NEW
by hippo (Archbishop) on Aug 23, 2017 at 19:17 UTC

    You get no results because your code doesn't compile.

    $ perl -cw 1197885.pl Global symbol "$line" requires explicit package name at 1197885.pl lin +e 8. Global symbol "$line" requires explicit package name at 1197885.pl lin +e 9. Unrecognized character \x91; marked by <-- HERE after $line .= <-- + HERE near column 12 at 1197885.pl line 9.

    Declare all your lexical variables and fix the dodgy characters in the source and see how far you get. I suspect that Print will be the next thing to bite you.

Re: Unpack and Print NEW
by johngg (Canon) on Aug 23, 2017 at 22:08 UTC

    Further to the comments from hippo and afoken, I'm a little puzzled by your input (when downloaded) and your expected output as the alignment seems inconsistent. Have you perhaps pasted some TAB characters in there?

    Regarding your code:-

    • Use of lexical rather than package file handles is now recommended and I would suggest that the error messages on open failure be differentiated with the file name so that you know immediately which failed rather than having to do some detective work.

    • Your

      while (<FILE>) { $line = $_;

      could more simply be written

      while ( my $line = <FILE> ) {

    • You pad the line to a length of 280 characters but you have forgotten to chomp the line terminator off before padding so you have a line terminator left in the middle.

    • A simpler way to pad lines with spaces is to use pack with the A template, for example:-

      johngg@shiraz:~/perl/Monks > perl -Mstrict -Mwarnings -E ' my $text = q{abcd}; say qq{>$text<}; $text = pack q{A10}, $text; say qq{>$text<};' >abcd< >abcd < johngg@shiraz:~/perl/Monks > perl -Mstrict -Mwarnings -E ' my $text = q{abcd}; say qq{>$text<}; $text = pack q{A2}, $text; say qq{>$text<};' >abcd< >ab<

    • Rather than unpacking into several scalars do so into an array and then apply double quotes to the relevant items using an array slice, something like this:-

      johngg@shiraz:~/perl/Monks > perl -Mstrict -Mwarnings -E ' my @items = q{a} .. q{g}; s{(.*)}{"$1"} for @items[ 0, 1, 3, 5, 6]; say for @items;' "a" "b" c "d" e "f" "g"

    • Rather than multiple print statements, perhaps use a single say (if running perl 5.10 or later) and join all the items together with commas in one fell swoop, something like

      say join q{,}, @items;

    I hope these pointers are helpful and you are able to move towards a solution. Please ask further if difficulties persist.

    Cheers,

    JohnGG

Re: Unpack and Print NEW
by kcott (Archbishop) on Aug 24, 2017 at 06:47 UTC

    G'day jlope043,

    You don't need to pad your lines with spaces: you can use 'A*' at the end of your template. See "perlpacktut - tutorial on pack and unpack".

    I don't know this Print function that you've used multiple times. Did you mean print? Did you fail to show us a subroutine definition for &Print? Did to fail to show a module you loaded which implements a Print function? I could just assume it's a typo, propagated twelve times, and print was in fact intended; however, your expected output bears no relation to what print statements would actually output.

    I don't think you really need to assign the results to that list of variables; you could proably just use the unpack result directly (see my code example below). By the way, there's another typo there: #amt3 should presumably be $amt3 (Perl will see #amt3 as the start of a comment and ignore it, and everything after it on that line).

    When working with comma-separated data, you should use Text::CSV. If you also have Text::CSV_XS installed, it will run faster. You can also use this for tab-, pipe-, or other_character-separated data.

    Given the number of unknowns, it's difficult to provide you with a solid solution. I will take a guess that what you want is close to something like this:

    #!/usr/bin/env perl -l use strict; use warnings; use Text::CSV; my $csv = Text::CSV::->new; while (<DATA>) { $csv->print(\*STDOUT, [ map { /^\s*(.*?)\s*$/ } unpack 'A3A9A9A*' +]); } __DATA__ 123 qwe, rty 04/05/06 X 456 asd, fgh 07/08/09 XX 789 zxc, vbn 01/02/03 XXX

    Output:

    123,"qwe, rty",04/05/06,X 456,"asd, fgh",07/08/09,XX 789,"zxc, vbn",01/02/03,XXX

    As a final piece of advice, pay more attention to what you're doing. You've been using Perl for a year or so now: it's fine that you haven't learnt about all the techniques and modules available, and we're happy to help you with that; it's most definitely not OK to post rubbish, and then state "when I run the process I get no results." — the first two responses you got[1,2] clearly show the results consisted of error messages, which you would have got too — this sort of thing doesn't fool us and doesn't help you. If you are genuinely unable to copy and paste your actual code, then say so, but at least make an effort to reproduce the real code; don't make up stories about how you ran it, along with fictitious claims about the output it produced.

    — Ken

Re: Unpack and Print NEW
by afoken (Chancellor) on Aug 23, 2017 at 19:22 UTC

    Your code does not even compile:

    X:\>perl 1197885.pl Global symbol "$line" requires explicit package name at 1197885.pl lin +e 8. Global symbol "$line" requires explicit package name at 1197885.pl lin +e 9. Unrecognized character \x91; marked by <-- HERE after $line .= <-- H +ERE near column 12 at 1197885.pl line 9. X:\>

    Please post the actual code using copy & paste. And by the way: Stupid quotes (“”) and standard quotes (") are not exchangeable in Perl.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)