Re: what's this loo code? (*slurp*)
by tye (Sage) on Feb 04, 2003 at 17:58 UTC
|
I waited and two explanations have already appeared as I hoped and expected...
But I wanted to mention my first impression when I saw that code in jmcnamara's node: "Oh, that takes way too much memory and will fail for files that don't fit within your available swap space".
The number of possible Perl one-liners that print a line count and don't suffer from requiring way too much memory for large files is quite huge. I'll shoot for a very straight-forward one:
perl -le '1 while <>; print $.' file
I'm almost certain you can make that faster or shorter (without reintroducing the memory hog aspect of it), but I really don't care to do either.
- tye
| [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
But I wanted to mention my first impression when I saw that code in jmcnamara's node: "Oh, that takes way too much memory and will fail for files that don't fit within your available swap space".
I hope you realise that I was aware of that. :-)
This snippet's only real value is as a mild curiosity. When I first posted it here I wrote: "There are many ways of doing this and most of them are better".
If I really wanted a line count I would use one of the following in this order of preference:
wc -l file
awk 'END{print NR}' file
perl -nle 'END{print $.}' file
--
John.
| [reply] [Watch: Dir/Any] [d/l] |
|
perl -ne'BEGIN{$/=\65536} $a+=tr/\n//; END{print"$a\n"}' file
Pity there's no way to set $/ to a reference to a number using a switch.
Makeshifts last the longest. | [reply] [Watch: Dir/Any] [d/l] |
|
If the last line doesn't end with a \n (that is, \n is not the last character in the last chunk) you'll be off by one.
| [reply] [Watch: Dir/Any] |
|
|
I guess the comments throw off my expectations, too. Since when does "wc" stand for "number of lines in a file"? The dictionary says it's a British toilet (a.k.a. "the loo") and it could be an acronym for word count, so I was trying to figure out how that was counting words.
| [reply] [Watch: Dir/Any] |
|
---
print map { my ($m)=1<<hex($_)&11?' ':'';
$m.=substr('AHJPacehklnorstu',hex($_),1) }
split //,'2fde0abe76c36c914586c';
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: what's this loo code?
by jdporter (Paladin) on Feb 04, 2003 at 17:44 UTC
|
| [reply] [Watch: Dir/Any] |
Re: what's this loo code?
by clairudjinn (Beadle) on Feb 04, 2003 at 20:43 UTC
|
I wrote to Larry about this sort of thing once:
me: The following is from page 75 in the Camel: "List assignment in scalar context returns the number of elements produced by the expression on the right side of the assignment:
$x = ( ($a, $b) = (7,7,7) ); #set $x to 3, not 2
why. how.
Larry on why: Because then you can use it for a boolean value:
while (($a,$b) = somefunc()) { ... }
If it used the number of elements on the left, it would always be true.
Larry on how: It counts them. :-) | [reply] [Watch: Dir/Any] [d/l] [select] |
Re: what's this loo code?
by BrowserUk (Patriarch) on Feb 04, 2003 at 19:04 UTC
|
If you just want the line count (no slurping).
perl -ne"}{die" file
If you want the filenames too
perl -ne"}{die$ARGV" *
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.
| [reply] [Watch: Dir/Any] [d/l] |
|
that's interesting. how does that '}{die' thing work ?
why doesn't perl complain of mismatched braces or something
| [reply] [Watch: Dir/Any] |
|
-p
causes Perl to assume the following loop around your program, which ma
+kes it iterate over filename arguments somewhat like sed:
LINE:while (<>) { # your program goes here }
continue { print or die "-p destination: $!\n"; }
If you substitute the 'program' eg. "}{die" where the comment above says " your program goes here", then you willl see how the thing works.
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead. | [reply] [Watch: Dir/Any] [d/l] |
Re: what's this loo code?
by pfaut (Priest) on Feb 04, 2003 at 17:49 UTC
|
I think whatever perl normally uses $= for is irrelevant. The idea is to use the assignment to a scalar to evaluate the array in scalar context. The anonymous array exists to evaluate the <> in list context. So, slurp the file into the anonymous array, then assign the size of the array to $= and print it.
---
print map { my ($m)=1<<hex($_)&11?' ':'';
$m.=substr('AHJPacehklnorstu',hex($_),1) }
split //,'2fde0abe76c36c914586c';
| [reply] [Watch: Dir/Any] [d/l] |
|
This is a bogus explanation I'm afraid. The anonymous array you speak of doesn't exist afaik, but I wouldn't bet my life on it. But what I'm sure of is that then assign the size of the array to $= is wrong. From perlop: "a list assignment in scalar context returns the number of elements produced by the expression on the right hand side of the assignment." What's on the LHS is irrelevant.
print scalar(($a, $b) = ('a','b','c')); # prints '3'
ihb
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: what's this loo code?
by steves (Curate) on Feb 04, 2003 at 17:55 UTC
|
I don't see the point, but breaking it down:
- Read from file: <>
- Read in array context; i.e., get all lines from file: ()=<>
- Assign those read lines to $=. That's the page length for formatted output: $==()
Basically it's saying, make the format page length the size of the number of lines in file. But just printing that doesn't really do a whole lot unless I'm missing something ...
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] [d/l] |
Re: what's this loo code?
by Anonymous Monk on Feb 05, 2003 at 03:51 UTC
|
looks like:
the whole contents of file are being read by =<> into an anonymous scalar =() and assigned to the lines per page variable $=
...so that to me means the whole file is printed as one page, ie no "press any key to continue" during viewing. I might not be perfect in my interpretation, but i don't think it's far off the mark either.
chris_piechowicz@hotmail.com | [reply] [Watch: Dir/Any] |