in reply to Write to multiple files according to multiple regex

If the format of your input file allows it, you could work with blocks instead of lines by setting $INPUT_RECORD_SEPARATOR ($/) to '^END_OF_BLOCK'.
Bill
  • Comment on Re: Write to multiple files according to multiple regex

Replies are listed 'Best First'.
Re^2: Write to multiple files according to multiple regex
by Foodeywo (Novice) on Jul 21, 2015 at 12:43 UTC

    nice hint thanks, I didn't know that thing.

    I did this:

    $/ = '^END';

    and within the while

    print {$filehandles[$i]} $line if $line=~/$regex[$i]/;

    this seems to be much faster (i guess this is all it is about, right?

    Last problem remaining is that everything is written to the last filehandler. I cant see why that is the case.

      Last problem remaining is that everything is written to the last filehandler. I cant see why that is the case.

      It looks to me like you are overwriting $ofh on each iteration of the first loop where you set up the array of handles. This would mean that every entry in your array points to the same file (the last file, of course). If you use a local variable inside that loop you may solve the problem. HTH.

        thanks. how would that look like?

        I did something like this

        foreach(@inputs) { #localize the file glob, so FILE is unique to # the inner loop. local *FILE; local *OUTFILE; #NEW $file = "$FindBin::Bin/../rxo/$_"; $outfile = "$FindBin::Bin/../blocks/$_"; open(*FILE, "$file") || die; open(*OUTFILE, "> $outfile") || die; #NEW: added a star #push the typeglobe to the end of the array $fh = \*FILE; $ofh = \*OUTFILE; $regex = <$fh>; push(@regex,$regex); push(@filehandles,$ofh); }

        this results in a new error "print() on unopened filehandle OUTFILE"

        hm. i probably solved it, not 100% sure.

        i did

        local *OUTFILE; open(OUTFILE, "> $outfile") || die; push(@filehandles,*OUTFILE);

        now the script writes to all files (but not the correct contents)

      aha. i just noticed. it does not work. using the really big file gives me an "out of memory" after a few seconds. maybe I used it the wrong way?

      update: it must be "END" not "^END". with "^" it just prints everything from first match to the end of the file. however if i use

      $/ = 'END';

      it prints the first match (correctly) and (meanwhile) to the correct file, but it stops parsing afterwards.