Hi,
If one runs `head --lines=-0 somefile', he'll sometimes get no output instead
of full file contents as
expected after reading the manual:
-n, --lines=[-]K
print the first K lines instead of the first 10; with the lead‐
ing `-', print all but the last K lines of each file
It depends on whether the file has a trailing newline.
For example:
$ printf '1\n2\n3' > test1
$ printf '4\n5\n' > test2
$ head -n -0 test*
==> test1 <==
==> test2 <==
4
5
$ tail -n +0 test* # Just for comparison
==> test1 <==
1
2
3
==> test2 <==
4
5
$
I'm using Debian GNU/Linux 7 wheezy and coreutils-8.13; I've also tested
coreutils-8.22, and it has the
same issue.
A proposed patch fixing the bug is attached. It makes head behave exactly like
`tail -n +0' on same files.
--
Алексей Шилин--- coreutils-8.22.orig/src/head.c 2013-12-04 14:48:30.000000000 +0000
+++ coreutils-8.22/src/head.c 2014-01-03 14:49:44.344272895 +0000
@@ -636,8 +636,11 @@
return false;
}
+ /* n_lines == 0 case needs special treatment. */
+ const bool all_lines = !n_lines;
+
/* Count the incomplete line on files that don't end with a newline. */
- if (bytes_read && buffer[bytes_read - 1] != '\n')
+ if (n_lines && bytes_read && buffer[bytes_read - 1] != '\n')
--n_lines;
while (1)
@@ -647,11 +650,16 @@
size_t n = bytes_read;
while (n)
{
- char const *nl;
- nl = memrchr (buffer, '\n', n);
- if (nl == NULL)
- break;
- n = nl - buffer;
+ if (all_lines)
+ n -= n ? 1 : 0;
+ else
+ {
+ char const *nl;
+ nl = memrchr (buffer, '\n', n);
+ if (nl == NULL)
+ break;
+ n = nl - buffer;
+ }
if (n_lines-- == 0)
{
/* Found it. */