commit: e3dc53404bd34234de0803f671ba0e57aa9d562c
parent 40752967b170218b7e93b5d32a046c2c90ac4304
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Tue, 4 Jun 2024 07:38:02 +0200
cmd/head: Add support for historical -num
Diffstat:
3 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/cmd/head.1 b/cmd/head.1
@@ -10,7 +10,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl qv
-.Op Fl c Ar size | Fl n Ar num
+.Op Fl c Ar size | Fl n Ar num | Fl Ar num
.Op Ar file...
.Sh DESCRIPTION
.Nm
@@ -35,11 +35,17 @@ in each
can be multiplied by one of KMGTP (Kilo, Mega, Giga, Tera, ...)
using power of 1024 by default, which can be either explicit via adding iB
(like MiB), or turned into powers of 1000 by adding B (like MB).
-.It Fl n Ar num
+.It Fl n Ar num , Fl Ar num
Read the first
.Ar num
lines in each
.Ar file .
+.Pp
+The
+.Fl Ar num
+form is historical, new scripts should use the standard
+.Fl n Ar num
+form.
.It Fl q
Don't print header when multiple
.Ar file
@@ -81,5 +87,8 @@ The
and
.Fl v
options are extensions.
+The
+.Fl Ar num
+option is historical.
.Sh AUTHORS
.An Haelwenn (lanodan) Monnier Aq Mt contact+utils@hacktivis.me
diff --git a/cmd/head.c b/cmd/head.c
@@ -7,6 +7,7 @@
#include "../lib/truncation.h" // apply_size_suffix
#include <assert.h>
+#include <ctype.h> // isdigit
#include <errno.h>
#include <fcntl.h> // open
#include <stdio.h> // fprintf, fopen, fread
@@ -148,7 +149,7 @@ copy_lines(char *filename)
static void
usage()
{
- fprintf(stderr, "Usage: head [-qv] [-c size | -n num] [file...]\n");
+ fprintf(stderr, "Usage: head [-qv] [-c size | -n num | -num] [file...]\n");
}
int
@@ -157,9 +158,34 @@ main(int argc, char *argv[])
int (*copy_action)(char *filename) = copy_lines;
int print_header = 0;
- int c = -1;
- while((c = getopt(argc, argv, ":qvc:n:")) != -1)
+ while(optind < argc)
{
+ /* Skip getopt(3) for parsing -num option due to how it works:
+ * - optstring = "12"; args="head -12" considered the same as -1 -2
+ * - optstring = "1:"; args="head -12" considered the same as -1 2
+ *
+ * And we need args="head -12" as "12"
+ */
+ if(argv[optind] && argv[optind][0] == '-' && isdigit(argv[optind][1]))
+ {
+ assert(errno == 0);
+ char *arg = argv[optind] + 1;
+
+ char *endptr = NULL;
+ lines = strtoul(arg, &endptr, 0);
+ if(errno != 0)
+ {
+ fprintf(stderr, "head: Error while parsing number for `-%s`: %s\n", arg, strerror(errno));
+ return 1;
+ }
+
+ optind++;
+ continue;
+ }
+
+ int c = getopt(argc, argv, ":qvc:n:");
+ if(c == -1) break;
+
switch(c)
{
case 'q':
diff --git a/test-cmd/head.t b/test-cmd/head.t
@@ -27,6 +27,13 @@
4
5
+ $ seq 1 20 | head -5
+ 1
+ 2
+ 3
+ 4
+ 5
+
$ seq 1 5 | head
1
2