Skip site navigation (1)Skip section navigation (2)
Date:      5 Oct 2000 12:58:02 -0000
From:      "Peter Pentchev" <roam@orbitel.bg>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/21766: [PATCH] add -s (skip) flag to head(1)
Message-ID:  <20001005125802.7108.qmail@ringwraith.office1>

next in thread | raw e-mail | index | archive | help

>Number:         21766
>Category:       bin
>Synopsis:       [PATCH] add -s (skip) flag to head(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 05 06:00:04 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     "Peter Pentchev" <roam@orbitel.bg>
>Release:        FreeBSD 4.1.1-STABLE i386
>Organization:
Orbitell JSCo.
>Environment:

FreeBSD 4.1.1-STABLE #1: Thu Oct  5 13:13:32 EEST 2000

>Description:

It is sometimes useful to display, say, the *second* 20 lines of a file.
Yes, I am perfectly aware that head -40 | tail -20 works, but having
head(1) able to skip lines/bytes is a little bit better in my book :)

The attached patch adds a -s flag, expecting a numeric argument; that
number of lines/bytes is skipped, after which the quantity requested
by -n or -c (or the implicit 10) are displayed as usual.
  
>How-To-Repeat:

Try to display the second 20 (or 800 in my case) lines of a file;
watch yourself go through loops ;)

>Fix:

diff -urN src/usr.bin/head/head.1 mysrc/usr.bin/head/head.1
--- src/usr.bin/head/head.1	Sat Aug 28 04:01:58 1999
+++ mysrc/usr.bin/head/head.1	Thu Oct  5 15:43:08 2000
@@ -42,6 +42,7 @@
 .Nm head
 .Op Fl n Ar count
 .Op Fl c Ar bytes
+.Op Fl s Ar skipcount
 .Op Ar file ...
 .Sh DESCRIPTION
 This filter displays the first
@@ -60,6 +61,14 @@
 where
 .Dq XXX
 is the name of the file.
+.Pp
+If
+.Ar skipcount
+is specified, the
+.Nm head
+utility skips the specified number of lines or bytes before displaying
+the requested
+.Ar count .
 .Pp
 The
 .Nm head
diff -urN src/usr.bin/head/head.c mysrc/usr.bin/head/head.c
--- src/usr.bin/head/head.c	Sat Aug 28 04:01:58 1999
+++ mysrc/usr.bin/head/head.c	Thu Oct  5 15:37:31 2000
@@ -60,8 +60,8 @@
  * Bill Joy UCB August 24, 1977
  */
 
-void head __P((FILE *, int));
-void head_bytes __P((FILE *, int));
+void head __P((FILE *, int, int));
+void head_bytes __P((FILE *, int, int));
 void obsolete __P((char *[]));
 void usage __P((void));
 
@@ -74,11 +74,11 @@
 {
 	register int ch;
 	FILE *fp;
-	int first, linecnt = -1, bytecnt = -1;
+	int first, linecnt = -1, bytecnt = -1, skipcnt = 0;
 	char *ep;
 
 	obsolete(argv);
-	while ((ch = getopt(argc, argv, "n:c:")) != -1)
+	while ((ch = getopt(argc, argv, "n:c:s:")) != -1)
 		switch(ch) {
 		case 'c':
 			bytecnt = strtol(optarg, &ep, 10);
@@ -90,6 +90,11 @@
 			if (*ep || linecnt <= 0)
 				errx(1, "illegal line count -- %s", optarg);
 			break;
+		case 's':
+			skipcnt = strtol(optarg, &ep, 10);
+			if (*ep || skipcnt <= 0)
+				errx(1, "illegal skip count -- %s", optarg);
+			break;
 		case '?':
 		default:
 			usage();
@@ -113,40 +118,49 @@
 				    first ? "" : "\n", *argv);
 				first = 0;
 			}
-			if (bytecnt == -1)
-				head(fp, linecnt);
-			else
-				head_bytes(fp, bytecnt);
+			if (bytecnt == -1) {
+				if (skipcnt) head(fp, skipcnt, 0);
+				head(fp, linecnt, 1);
+			} else {
+				if (skipcnt) head_bytes(fp, skipcnt, 0);
+				head_bytes(fp, bytecnt, 1);
+			}
 			(void)fclose(fp);
 		}
 	}
-	else if (bytecnt == -1)
-		head(stdin, linecnt);
-	else
-		head_bytes(stdin, bytecnt);
+	else if (bytecnt == -1) {
+		if (skipcnt) head(stdin, skipcnt, 0);
+		head(stdin, linecnt, 1);
+	} else {
+		if (skipcnt) head_bytes(stdin, skipcnt, 0);
+		head_bytes(stdin, bytecnt, 1);
+	}
 
 	exit(eval);
 }
 
 void
-head(fp, cnt)
+head(fp, cnt, out)
 	FILE *fp;
 	register int cnt;
+	int out;
 {
 	register int ch;
 
 	while (cnt && (ch = getc(fp)) != EOF) {
+		if (out)
 			if (putchar(ch) == EOF)
 				err(1, "stdout");
-			if (ch == '\n')
-				cnt--;
-		}
+		if (ch == '\n')
+			cnt--;
+	}
 }
 
 void
-head_bytes(fp, cnt)
+head_bytes(fp, cnt, out)
 	 FILE *fp;
 	 register int cnt;
+	 int out;
 {
 	char buf[4096];
 	register int readlen;
@@ -159,8 +173,9 @@
 		readlen = fread(buf, sizeof(char), readlen, fp);
 		if (readlen == 0)
 			break;
-		if (fwrite(buf, sizeof(char), readlen, stdout) != readlen)
-			err(1, "stdout");
+		if (out)
+			if (fwrite(buf, sizeof(char), readlen, stdout) != readlen)
+				err(1, "stdout");
 		cnt -= readlen;
 	}
 }

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001005125802.7108.qmail>