in reply to Re: Re: Insert at regular increments
in thread Insert at regular increments

how would I use this approach to add newlines after every record in the file (i.e. after every 320 characters)?
Take advantage of the $/ variable
{ open(my $data, '<', "data_file") or die("ack - $!"); open(my $out, '>', "out_file") or die("ack - $!"); local $/ = \320; while(<$data>) { chomp; print $out $_ . "\n"; } }

HTH

_________
broquaint

Replies are listed 'Best First'.
Re: Re: Re: Re: Insert at regular increments
by sauoq (Abbot) on Jul 22, 2002 at 22:32 UTC

    Using $/ is a nice esoteric idea requiring the person to really know perl in order to understand the code... but it won't work unless you already know that the file doesn't have the record separators. (In which case you wouldn't need chomp().) If I read the question correctly, the records themselves are 320 characters, not 319 characters plus a newline. If the file already has newlines, the first newline will become the first character in the second record and everything will get even more squirrely after that.

    If you are going to use it, besides pre-determining the existence of newlines, I suggest use English; and $INPUT_RECORD_SEPARATOR as well as comments explaining the magic for the uninitiated.

    -sauoq
    "My two cents aren't worth a dime."
    
      Thanks, sauoq. Agreed, using $/ may be a little more obscure, but it is the type of record-based solution I was looking for. I wouldn't run into the newline problem since I first check to see whether the file needs the mod in the first place (although you suggested a much more concise way of performing that check in another reply, so thanks for that too!).

      -P

      Using $/ is a nice esoteric idea requiring the person to really know perl in order to understand the code...
      I'd saying changing the value of $/ to alter how a file is read in is pretty idiomatic perl[1], and failing that knowledge there was a link to the perlvar manpage.
      but it won't work unless you already know that the file doesn't have the record separators.
      If the records are delimited by 320 character chunks then the code should work as it'll remove any existing newlines then append one. If it gets much more complex than that then some seek()ing and closer examination of the data will be needed.
      HTH

      _________
      broquaint

      [1] what's more, setting $/ to an integer reference was implemented with record-oriented files in mind

      update: reworded the second paragraph to be more accurate/less wrong (thanks for the heads-up Aristotle)

        Looks as though that's the case; if I understood correctly, bad files have 320 character records and good ones have 322 character ones.

        Makeshifts last the longest.

        I'd saying changing the value of $/ to alter how a file is read in is pretty idiomatic perl, and failing that knowledge there was a link to the perlvar manpage.

        I'm quite comfortable with using $/ myself but in the real world not everyone knows perl as well as you or I. Many people, even those who are aware of $/, have never seen it used for fixed length records. My suggestion was to use English;[1]. If it were a one-liner I'd use $/ but in a program which needs to be maintained it is best to type the extra characters in $INPUT_RECORD_SEPARATOR and to add some comments too.

        If the records are delimited by 320 character chunks then the code should work as it'll remove any existing newlines then append one.

        To show the problem with the solution you provided, consider a record length of 3 characters and the string "abc\ndef" as input. (We'll ignore the fact that the delimiter was actually CRLF as it doesn't make your solution any more correct.) Your code would read in "abc" and append a newline to it. The next loop would read in "\nde" and append a newline to it... etc. Does that explanation make more sense?

        -sauoq
        "My two cents aren't worth a dime.";
        
        [1]What's more, use English; was implemented with maintainability in mind. :-P
Re: Re: Re: Re: Insert at regular increments
by EyeOpener (Scribe) on Jul 22, 2002 at 22:01 UTC
    That's what I was looking for! I knew there was nice native support for dealing with fixed-length records. Much reading to do... Thanks broquaint!