Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re: Printing a String (TOO stupid?)

by AnomalousMonk (Canon)
on Jun 18, 2014 at 06:16 UTC ( #1090257=note: print w/replies, xml ) Need Help??

in reply to Printing a String (TOO stupid?)

Possibly the chomp-ed  $line still has a carriage-return at the end of it.

c:\@Work\Perl\monks>perl -wMstrict -le "my $line = qq{01234567\x0d}; print qq{It was $line!!!\n}; " !!!was 01234567

This might arise if, e.g., the file had been created on a Windows system (with  \x0d\x0a line-enders) and then transferred to a *nix system without proper newline translation. On the *nix system, chomp will take care of the  \x0a but leave the  \x0d untouched.

(BTW: It may or may not be too stupid, but the reason I know about this sort of thing is that I've done it myself — and more than once!)

Replies are listed 'Best First'.
Re^2: Printing a String (TOO stupid?)
by jimson (Initiate) on Jun 18, 2014 at 07:12 UTC

    Seems exactly so. I tested using 'chop' twice, which finally work.

    However, this would make the code only work for Windows. Any suggestion on how to let such codes portable to Unix?

      Probably the best approach would be to do a proper system-to-system transfer in the first place. (Update: On second thought, see below for probable BP.) E.g., the ftp utility common to most (all?) OSen has an ascii mode (automatic line-end translation) as well as a binary (don't touch nuthin') mode.

      Otherwise, doing something like
          $line =~ s{ [\x0d\x0a]+ \z }{}xms;
      to each and every line would do the trick to eliminate any possible combination of  \x0d and  \x0a characters from the end of the line. Other regexes can handle more particular combinations of line-enders.

        Ugh. I prefer transfers to remain as dumb as possible, as usually somebody switches to compressed files instead of text files somewhere down the road. Also, finding out whether two data deliveries are the same becomes really hard if their checksums and filesizes don't match at either end.

        So I'm firmly in the latter camp of doing the conversion in Perl instead of doing the conversion at transfer time.


      I was wrong. Somehow, I remembered it working differently.

      But { local $/ = ''; chomp($x); } seems to work. Needs more testing and I'm not sure there would still be a performance benefit.

      Try chomp; chomp; instead of chop; chop;

      chomp is conditional. Being built in, I would expect it to be more efficient than a regex.

        That's wrong in this specific case. Here, you have a Windows file with "\r\n" line ends. Under Unix, the chomp command will remove only the "\n" part, but not the "\r". Using chomp a second time will not remove the "\r" under Unix. So the printing goes back to line start and the three !!! overwrite the beginning of the line.

        The best solution here is to remove the "\r":

        chomp $line; $line =~ s/\r//g;
        $line =~ s/[\r\n]//g;

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1090257]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2017-03-25 02:47 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (310 votes). Check out past polls.