On 19/07/2023 15:32, Martin Castillo wrote:
Hi,

I noticed an asymmetry between head and tail regarding the -n +N syntax
of tail.

For context, I was calculating checksums of 1 GiB chunks of a big file a la:
for i in $(seq 500); do head -c 1G | sha1sum >chunk-$i.sha1; done < bigfile

This was interrupted and I tried to continue by prepending

tail -c +270G bigfile | for i in $(seq 270 500); … ,

but I noticed I got unexpected results. The offset of +270G is one
based, so it started one byte to early.

And I wondered why that is.

I mean head -3 and tail 3 are complementary:
$ seq 10|head -n -3
1
2
3
4
5
6
7
$ seq 10|tail -n 3
8
9
10

But head 3 and tail +3 are not:

$ seq 10|head -n 3
1
2
3
$ seq 10|tail -n +3
3
4
5
6
7
8
9
10

This should be documented a bit more clearly and maybe be included in
the gotchas list.

I assume, this is because lines are numbered one-based, so this is more
intuitive to use. But when working with bytes, one usually uses offsets.
Is there a more intuitive way to get the last part of a file given an
offset?

I agree that `tail -n +NUM` usage is very unintuitive,
which I usually hit when skipping a header line with `tail -n +2`.
Unfortunately it's specified like this by POSIX.

I've updated the gotchas page with some relevant info:
http://www.pixelbeat.org/docs/coreutils-gotchas.html#tail

cheers,
Pádraig

Reply via email to