Purely In The Interests Of Science, I present an implementation of torso
, the logical middle between head
and tail
.
In practice, as others have noted, this is really unnecessary since you can get the desired output yourself by a trivial combination of head
and tail
.
#!/bin/sh
usage () {
printf "$0: $0 [-c <byte> -C <byte>] [-n <line> -N <line>] file [file ... ]\n"
}
while [ $# -gt 0 ] ; do
case "$1" in
-c|--byte-start) shift ; start="$1" ; mode=byte ; shift ;;
-C|--byte-end) shift ; end="$1" ; mode=byte ; shift ;;
-n|--line-start) shift ; start="$1" ; mode=line ; shift ;;
-N|--line-end) shift ; end="$1" ; mode=line ; shift ;;
--) shift ;;
-*) printf "bad option '%s'\n" "$1" ; usage ; exit 201 ;;
*) files=("${files[@]}" "$1") ; shift ;;
esac
done
if [ $start -gt $end ] ; then
printf "end point cannot be before start point\n"
usage
exit 202
fi
head_cmd=
tail_cmd=
end=$((end - start))
if [ $mode = "line" ] ; then
head_cmd="-n $end"
tail_cmd="-n +$start"
elif [ $mode = "byte" ] ; then
head_cmd="-c $end"
tail_cmd="-c +$start"
fi
if [ ${#files[@]} -eq 0 ] ; then
cat - | tail $tail_cmd | head $head_cmd
else
tail $tail_cmd "${files[@]}" | head $head_cmd
fi
To keep it topical, here's how to use torso
to solve the question:
torso -n 1500 -N 2500 input_file | grep -n "test"
Or for output conforming to the requirements
for file in sample_{1,2,7,10} ; do
printf "\n\n%s:\n\n" "$file"
torso -n 1500 -N 2500 "$file" | grep -n "test"
done
You may begin your criticisms... now!
is it possible with using grap instead of program, – bharanikumar – 2011-01-25T08:43:36.673
@Dennis Williamson: 'print FILENAME' could be put into the BEGIN { } as well... @bharanikumar: why are you so obsessed with grep? use the right tool for the problem and do not try to use the one hammer you have found somewhere and now everything you see is nails. – akira – 2011-01-25T09:21:49.307
1@akira: From
man gawk
: "FILENAME is undefined inside the BEGIN block (unless set by getline)." @bharanikumar: You could do it withgrep
if you usedhead
andtail
, but you'd lose line numbering and filename labeling. – Paused until further notice. – 2011-01-25T15:43:24.743Though it's more efficient to write this as one script I can't help but thinking that this is a missing tool. As a complement to head and tail, a tool that gives you a specific range of lines or bytes out of the middle of a stream (based on offset from the start). We could call it torso or thorax. – phogg – 2011-01-25T15:56:23.890
1
@phogg: I like "torso"! However, "thorax" excludes the abdomen and we can't do that because it's the "guts" of the file that we're really interested in. Having a tool like "torso" probably violates at least one principle in the Unix philosphy since
– Paused until further notice. – 2011-01-25T16:22:27.970head|tail
does the job adequately.Combining head and tail with a pipe does this quite neatly, but the problem is retaining the line numbers is tricky. Sed can also do this quite simply, but it can't print the filename. – Flexo – 2011-01-25T16:59:23.990
@Alan: Also, I find line-number output in
sed
to be unsatisfactory. – Paused until further notice. – 2011-01-25T17:48:46.673It's a shame you can't use it in a pattern match or substitution. – Flexo – 2011-01-25T18:09:01.977
You're all quite right, but just for fun I added an answer using
torso
. I sidestepped the line number question by pretending that it doesn't exist. – phogg – 2011-01-25T19:37:52.903