Skip to content

Instantly share code, notes, and snippets.

@obfusk
Last active December 19, 2015 09:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save obfusk/5935539 to your computer and use it in GitHub Desktop.
Save obfusk/5935539 to your computer and use it in GitHub Desktop.
head+tail with perl
# One-line version of head-and-tail.plx (w/o --no-overlap and w/o
# proper handling of tail less than number of lines):
seq 1 100000 | HEAD=5 TAIL=2 SEP=$'...\n' perl -e 'my($h,$t,$s,$l)=($ENV{"HEAD"}||10,$ENV{"TAIL"}||10,$ENV{"SEP"}||"",0);my @b=();while(<>){print if $.<=$h;$b[$.%$t]=$_;$l=$.};print $s;for(my $i=$t-1;$i>=0;--$i){print $b[($l-$i)%$t]}'
# For files (not streams), this seems to work just fine too (but it
# will not overlap):
( head -n 5; echo ...; tail -n 2 ) < some-file
# Also: all 3 will always print the ... even if head and tail are
# contiguous.
#!/usr/bin/perl -w
# Example:
# $ seq 1 100000 | head-and-tail.plx -h 3 -t 2 --sep $'...\n'
# 1
# 2
# 3
# ...
# 99999
# 100000
use strict; use Getopt::Long;
my ($head, $tail, $sep, $overlap) = (10, 10, '', 1);
my $last = 0; my @buf = ();
GetOptions (
'head=i' => \$head, 'tail=i' => \$tail, 'sep=s' => \$sep,
'overlap!' => \$overlap
) or die ('Error in command line arguments.');
while (<>)
{
print if $. <= $head; $buf[$. % $tail] = $_; $last = $.;
}
print $sep;
my $t1 = $tail > $last ? $last : $tail;
my $t2 = !$overlap && $last - $head < $t1 ? $last - $head : $t1;
for (my $i = $t2 - 1; $i >= 0; --$i)
{
print $buf[($last - $i) % $tail];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment