I would like to generate a permutation of some lines. We have random,
which is vageuly similar. This adds a -p option to instead permute
instead of randomly select.
Index: random.6
===================================================================
RCS file: /cvs/src/games/random/random.6,v
retrieving revision 1.7
diff -u -p -r1.7 random.6
--- random.6 31 May 2007 19:19:18 -0000 1.7
+++ random.6 22 Dec 2014 20:57:06 -0000
@@ -37,7 +37,7 @@
.Nd random lines from a file or random numbers
.Sh SYNOPSIS
.Nm random
-.Op Fl er
+.Op Fl epr
.Op Ar denominator
.Sh DESCRIPTION
.Nm
@@ -58,6 +58,8 @@ does not read or write anything, and sim
exit value of 0 to
.Ar denominator
\&- 1, inclusive.
+.It Fl p
+Read lines from standard input and output a permutation of all of them.
.It Fl r
The
.Fl r
Index: random.c
===================================================================
RCS file: /cvs/src/games/random/random.c,v
retrieving revision 1.12
diff -u -p -r1.12 random.c
--- random.c 27 Oct 2009 23:59:26 -0000 1.12
+++ random.c 22 Dec 2014 20:55:31 -0000
@@ -40,6 +40,7 @@
#include <err.h>
#include <errno.h>
#include <stdio.h>
+#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
@@ -47,6 +48,42 @@
void usage(void);
+static void
+permute(void)
+{
+ char **array = NULL;
+ size_t numlines = 0;
+ size_t maxlines = 0;
+ size_t linelen;
+ char *line;
+ size_t j;
+
+ while ((line = fgetln(stdin, &linelen))) {
+ if (line[linelen - 1] == '\n')
+ linelen--;
+ if (numlines == maxlines) {
+ maxlines = maxlines ? maxlines : 16;
+ array = reallocarray(array, maxlines,
+ 2 * sizeof(char *));
+ if (!array)
+ err(1, "out of memory");
+ maxlines *= 2;
+ }
+ if (!(array[numlines] = strndup(line, linelen)))
+ err(1, "out of memory");
+ numlines++;
+ }
+ for (j = numlines; j > 1; j--) {
+ size_t s = arc4random_uniform(j);
+ char *tmp = array[s];
+ array[s] = array[j - 1];
+ array[j - 1] = tmp;
+ }
+ for (j = 0; j < numlines; j++)
+ puts(array[j]);
+}
+
+
int
main(int argc, char *argv[])
{
@@ -55,7 +92,7 @@ main(int argc, char *argv[])
char *ep;
random_exit = unbuffer_output = 0;
- while ((ch = getopt(argc, argv, "erh")) != -1)
+ while ((ch = getopt(argc, argv, "eprh")) != -1)
switch (ch) {
case 'e':
random_exit = 1;
@@ -63,6 +100,9 @@ main(int argc, char *argv[])
case 'r':
unbuffer_output = 1;
break;
+ case 'p':
+ permute();
+ return (0);
default:
case '?': case 'h':
usage();