0

I am using perl to extract "Yes," or "No," from a large CSV, and output to a file using this code

open my $fin, "leads.csv";
my $str;
for (<$fin>) {                
  if (/^\s*\d+\.\s*(\w+)/) {  
    $str .= $1 . ",";         
  }
}
open (MYFILE, '>>data.txt');
 print MYFILE $str;
 close (MYFILE);

This is working correctly, and outputting data like this http://pastebin.com/r7Lwwz8p, however I need to break to a new line after the 16th element so it looks like this on output: http://pastebin.com/xC8Lyk5R Any tips/tricks greatly appreciated!

Miller
  • 34,962
  • 4
  • 39
  • 60
  • before you look for tips/tricks, try to reason through how you would accomplish the task and try to write some simple code that does that – ysth Apr 18 '14 at 02:26

2 Answers2

1

The following splits a line by commas, and then regroups them by 16 elements:

use strict;
use warnings;

while (my $line = <DATA>) {
    chomp $line;

    my @fields = split ',', $line;

    while (my @data = splice @fields, 0, 16) {
        print join(',', @data), "\n";
    }
}

__DATA__
LineA,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,LineB,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,LineC,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,LineD,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,LineE,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,LineF,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,LineG,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,LineH,2,3,4,5,6,7,8,9,10,11,12

Outputs:

LineA,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
LineB,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
LineC,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
LineD,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
LineE,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
LineF,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
LineG,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
LineH,2,3,4,5,6,7,8,9,10,11,12
Miller
  • 34,962
  • 4
  • 39
  • 60
0

Use a variable to count the number of yes/no matches that you find, and then use the mod (%) operator to insert a newline into the string.

#!/usr/bin/perl

use strict;
use warnings;

open my $fin, "leads.csv";
my $str;
my $count = 0;                
for (<$fin>) {
   if (/^\s*\d+\.\s*(\w+)/) {
     $str .= $1 . ",";
     $count++;         
   }
   $str .= "\n" unless ($count % 16);
}
open (MYFILE, '>>data.txt');
print MYFILE $str;
close (MYFILE);
msy2
  • 21
  • 3
  • Always include `use strict;` and `use warnings;` at the top of each and every perl script. Even example scripts like this. And yes, it's not required to use a lexical filehandle like `$fin`, but you really should unless there is a specific reason why you can't use one. – Miller Apr 18 '14 at 02:22
  • Interesting, I've never used the lexical filehandles before and I don't remember seeing it in the perl documenation before, but now that I'm searching for it, I see both types of examples ... learn something new everyday. Oh, and I normally use strict/warnings for my own stuff, but I didn't think it was pertinent to question, though I see the value in being consistent for answering questions. I'll edit my answer. – msy2 Apr 18 '14 at 02:29
  • 1
    Yes, at least half the new users to stackoverflow require being educated about [`use strict and warnings`](http://stackoverflow.com/questions/8023959/why-use-strict-and-warnings) so we aim to be consistent with that even with every example that we post. Thank you for adjusting. As for lexical file handles, they've been in existence for many years (sorry can't quite you exact figures), but they are much better because they limit their scope and automatically close the file handle when they lose scope. They also benefit from compile time error checking via `use strict;`, so they are ++ – Miller Apr 18 '14 at 02:34