SPUG: itm 60 in effective perl programming

John W. Krahn krahnj at telus.net
Thu Feb 24 02:33:26 PST 2005


Ben Reser wrote:
> On Wed, Feb 23, 2005 at 11:46:28PM -0800, Florentin Ionescu wrote:
> 
>>perl -pe 's/\n/" " . <>/e' file
>>is presented in Effective perl programming as program to join lines from a 
>>file.
>>what does it mean <> in this context ? - I looked into perlop and perlre 
>>but can't figure out haw it works.
> 
> <> is the null file handle.  In this case it reads the next line from
> the files given on the command line.
> 
> But I think their either is a typo in your example or in the book
> because that doesn't join the lines in the file:
> 
> $ echo 'foo' > test
> $ echo 'bar' >> test
> $ echo 'baz' >> test
> $ wc -l test
>       3 test
> $ perl -pe 's/\n/" " . <>/e' test
> foo bar

The two lines 'foo' and 'bar' *are* joined together!


> baz 
> 
> And in fact hangs until you Ctrl+D it if there is an odd number of lines
> in the file.

It didn't when I tried it and it shouldn't according to the documentation.


>  It hangs because the -p creates an implicit loop which
> reads from <> and then a second 

A second what?


> Perhaps they meant this:
> perl -pe 's/\n/ /' file
> 
> tr would probably be moderately better:
> perl -pe 'tr/\n/ /'
> 
> But I'd prefer the following:
> perl -pe 'chomp; $_ .= " "' file

Your examples replace *every* newline with a space which is not what the
original does.


> which would be faster.  Here's a quick and dirty comparision of
> execution times on a 4.2 GB file.
> 
> regex version:
> 31.06user 10.43system 2:19.48elapsed 29%CPU (0avgtext+0avgdata
> 0maxresident)k
> 0inputs+0outputs (0major+676minor)pagefaults 0swaps
> 
> tr version:
> 30.91user 7.45system 2:02.26elapsed 31%CPU (0avgtext+0avgdata
> 0maxresident)k
> 0inputs+0outputs (0major+651minor)pagefaults 0swaps
> 
> chomp version:
> 20.97user 9.89system 1:45.98elapsed 29%CPU (0avgtext+0avgdata
> 0maxresident)k
> 0inputs+0outputs (0major+652minor)pagefaults 0swaps
> 
> Be forwarned however, it might seem like you could get away with using
> chop instead of chomp here becuase you can count on every line having a
> line separater.  However, this won't work on Windows where text files
> are usually using two characters to separate lines.  chomp works because
> it will remove all of the characters that appear in $/ if the are at the
> end of the line.
> 
> I can't imagine why anyone would want to use the regex version.

Because the substitution operator allows you to _e_valuate the replacement
string as a perl expression.


>  So if
> what you gave was really what was printed in the book I'd say the book
> is wrong.

It looks fine to me.  :-)


John
-- 
use Perl;
program
fulfillment


More information about the spug-list mailing list