Subject: split into n chunks
To: None <tech-userlevel@netbsd.org>
From: Jan Schaumann <jschauma@netmeister.org>
List: tech-userlevel
Date: 05/28/2007 12:04:14
--yQbNiKLmgenwUfTN
Content-Type: multipart/mixed; boundary="yH1ZJFh+qWm+VodA"
Content-Disposition: inline


--yH1ZJFh+qWm+VodA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hello,

I've had the need to split a file into N chunks.  Now I could do the
math myself by looking at the file size and the specifying "-b" with the
appropriate number, but I figured it might be useful to let split(1) do
this for me.

The attached diff adds the "-n chunk_count" flag to split(1).

Does that look ok to commit?

-Jan

--=20
If you can read this, you're not the president.

--yH1ZJFh+qWm+VodA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff
Content-Transfer-Encoding: quoted-printable

Index: split.1
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/split/split.1,v
retrieving revision 1.13
diff -b -u -r1.13 split.1
--- split.1	7 Aug 2003 11:15:55 -0000	1.13
+++ split.1	28 May 2007 19:00:12 -0000
@@ -29,7 +29,7 @@
 .\"
 .\"	@(#)split.1	8.3 (Berkeley) 4/16/94
 .\"
-.Dd July 10, 2003
+.Dd May 28, 2007
 .Dt SPLIT 1
 .Os
 .Sh NAME
@@ -41,6 +41,7 @@
 .Oo
 .Fl b Ar byte_count Ns Oo Li k|m Oc |
 .Fl l Ar line_count
+.Fl n Ar chunk_count
 .Oc
 .Op Ar file Op Ar name
 .Sh DESCRIPTION
@@ -79,6 +80,10 @@
 Create smaller files
 .Ar line_count
 lines in length.
+.It Fl n
+Split file into
+.Ar chunk_count
+smaller files.
 .El
 .Pp
 If additional arguments are specified, the first is used as the name
Index: split.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/usr.bin/split/split.c,v
retrieving revision 1.21
diff -b -u -r1.21 split.c
--- split.c	5 Jan 2004 23:23:37 -0000	1.21
+++ split.c	28 May 2007 19:00:12 -0000
@@ -64,6 +64,7 @@
 static void newfile(void);
 static void split1(off_t);
 static void split2(off_t);
+static void split3(off_t);
 static void usage(void) __attribute__((__noreturn__));
 static size_t bigwrite(int, void const *, size_t);
=20
@@ -75,8 +76,9 @@
 	char const *base;
 	off_t bytecnt =3D 0;	/* Byte count to split on. */
 	off_t numlines =3D 0;	/* Line count to split on. */
+	off_t chunks =3D 0;	/* Number of chunks to split into. */
=20
-	while ((ch =3D getopt(argc, argv, "0123456789b:l:a:")) !=3D -1)
+	while ((ch =3D getopt(argc, argv, "0123456789b:l:a:n:")) !=3D -1)
 		switch (ch) {
 		case '0': case '1': case '2': case '3': case '4':
 		case '5': case '6': case '7': case '8': case '9':
@@ -119,6 +121,12 @@
 			    *ep !=3D '\0')
 				errx(1, "%s: illegal suffix length.", optarg);
 			break;
+		case 'n':		/* Chunks. */
+			if (!isdigit((unsigned char)optarg[0]) ||
+			    (chunks =3D (size_t)strtoul(optarg, &ep, 10)) =3D=3D 0 ||
+			    *ep !=3D '\0')
+				errx(1, "%s: illegal number of chunks.", optarg);
+			break;
 		default:
 			usage();
 		}
@@ -143,11 +151,16 @@
=20
 	if (numlines =3D=3D 0)
 		numlines =3D DEFLINE;
-	else if (bytecnt)
+	else if (bytecnt || chunks)
+		usage();
+
+	if (bytecnt && chunks)
 		usage();
=20
 	if (bytecnt)
 		split1(bytecnt);
+	else if (chunks)
+		split3(chunks);
 	else
 		split2(numlines);
=20
@@ -258,6 +271,26 @@
 }
=20
 /*
+ * split3 --
+ *	Split the input into specified number of chunks
+ */
+static void
+split3(off_t chunks)
+{
+	struct stat sb;
+	off_t bcnt;
+
+	if (fstat(ifd, &sb) =3D=3D -1) {
+		err(1, "stat");
+		/* NOTREACHED */
+	}
+
+	bcnt =3D sb.st_size/chunks;
+	bcnt +=3D sb.st_size%chunks;
+	split1(bcnt);
+}
+
+/*
  * newfile --
  *	Open a new output file.
  */
@@ -308,7 +341,7 @@
 usage(void)
 {
 	(void)fprintf(stderr,
-"usage: %s [-b byte_count] [-l line_count] [-a suffix_length] "
+"usage: %s [-b byte_count] [-l line_count] [-n chunk_count] [-a suffix_len=
gth] "
 "[file [prefix]]\n", getprogname());
 	exit(1);
 }

--yH1ZJFh+qWm+VodA--

--yQbNiKLmgenwUfTN
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (NetBSD)

iD8DBQFGWyeufFtkr68iakwRAsiiAJ4mb/Vx9isIJXyg/knAwKvzj8rHwgCfVOHg
4nLtT9rlQ0kONI54Jg7lIxI=
=wHNm
-----END PGP SIGNATURE-----

--yQbNiKLmgenwUfTN--