[comp.lang.perl] better head

tchrist@convex.COM (Tom Christiansen) (05/16/91)

Here's a little head clone I once wrote out of frustration 
with head's misbehaving on files with long lines.  


    #!/usr/bin/perl
    #
    # head -- perl clone of head command, but without heads silly 
    #	  limits regarding line lengths.  runs faster than 
    #	  C version, too!   tchrist@convex.com

    $num = ($ARGV[0] =~ /^-(.+)/ && shift) ? $1 : 10; 
    die "$0: badly formed number: $1\n" unless $num =~ /^\d+$/;

    unshift(@ARGV, '-') unless $argc = @ARGV;  # <> changes @ARGV
    while (<>) {
	if ($. == 1 && $argc > 1) {
	    print "\n" if $deja_imprime++;
	    print "=> $ARGV <=\n" ;
	}
	if ($. <= $num) {
	    print;
	} else {
	    close ARGV;
	} 
    } 
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time." 

rbj@uunet.uu.net (Root Boy Jim) (05/17/91)

tchrist@convex.COM (Tom Christiansen) writes:
>Here's a little head clone I once wrote out of frustration 
>with head's misbehaving on files with long lines.  

Piping to "head -#" is the same as piping to "sed #q".
Sed probably has problems with long lines too, tho.

>    #!/usr/bin/perl
>    #
>    # head -- perl clone of head command, but without heads silly 
>    #	  limits regarding line lengths.  runs faster than 
>    #	  C version, too!   tchrist@convex.com
>
>    $num = ($ARGV[0] =~ /^-(.+)/ && shift) ? $1 : 10; 
>    die "$0: badly formed number: $1\n" unless $num =~ /^\d+$/;
>
>    unshift(@ARGV, '-') unless $argc = @ARGV;  # <> changes @ARGV
>    while (<>) {
>	if ($. == 1 && $argc > 1) {
>	    print "\n" if $deja_imprime++;

It's deja vu all over again :-)

>	    print "=> $ARGV <=\n" ;
>	}

So far, so good.

>	if ($. <= $num) {
>	    print;
>	} else {
>	    close ARGV;
>	} 

I think you're reading too many lines.
Wouldn't "print; close ARGV if $. == $num" be better?

>    } 

I think you missed something tho.
What happens if some of the files have less than $num lines?
-- 
		[rbj@uunet 1] stty sane
		unknown mode: sane

tchrist@convex.COM (Tom Christiansen) (05/18/91)

From the keyboard of rbj@uunet.uu.net (Root Boy Jim):
:>    unshift(@ARGV, '-') unless $argc = @ARGV;  # <> changes @ARGV
:>    while (<>) {
:>	if ($. == 1 && $argc > 1) {
:>	    print "\n" if $deja_imprime++;
:
:It's deja vu all over again :-)

vraiment. :-)

:>	if ($. <= $num) {
:>	    print;
:>	} else {
:>	    close ARGV;
:>	} 
:
:I think you're reading too many lines.
:Wouldn't "print; close ARGV if $. == $num" be better?

I may be *reading* one line "too many", but at least 
the output is still right.

:I think you missed something tho.
:What happens if some of the files have less than $num lines?

It's true.  This works for those cases, too:

    #!/usr/bin/perl
    #
    # head -- perl clone of head command, but without head's silly 
    #	  limits regarding line lengths.  tchrist@convex.com

    $num = ($ARGV[0] =~ /^-(.+)/ && shift) ? $1 : 10; 
    die "$0: badly formed number: $1\n" unless $num =~ /^\d+$/;

    unshift(@ARGV, '-') unless $argc = @ARGV;  # <> changes @ARGV
    while (<>) {
	if ($. == 1 && $argc > 1) {
	    print "\n" if $deja_imprime++;
	    print "=> $ARGV <=\n" ;
	}
	print;
	close ARGV if $. == $num || eof;
    } 


--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time."