diff --git a/usr.bin/split/split.1 b/usr.bin/split/split.1 --- a/usr.bin/split/split.1 +++ b/usr.bin/split/split.1 @@ -28,7 +28,7 @@ .\" @(#)split.1 8.3 (Berkeley) 4/16/94 .\" $FreeBSD$ .\" -.Dd April 18, 2023 +.Dd May 26, 2023 .Dt SPLIT 1 .Os .Sh NAME @@ -151,7 +151,11 @@ .Dq Li a Ns - Ns Li z . If .Fl a -is not specified, two letters are used as the suffix. +is not specified, two letters are used as the initial suffix. +If the output does not fit into the resulting number of files and the +.Fl d +flag is not specified, then the suffix length is automatically extended as +needed such that all output files continue to sort in lexical order. .Pp If the .Ar prefix diff --git a/usr.bin/split/split.c b/usr.bin/split/split.c --- a/usr.bin/split/split.c +++ b/usr.bin/split/split.c @@ -75,6 +75,7 @@ static int pflag; static bool dflag; static long sufflen = 2; /* File name suffix length. */ +static int autosfx = 1; /* Whether to auto-extend the suffix length. */ static void newfile(void); static void split1(void); @@ -116,6 +117,7 @@ if ((sufflen = strtol(optarg, &ep, 10)) <= 0 || *ep) errx(EX_USAGE, "%s: illegal suffix length", optarg); + autosfx = 0; break; case 'b': /* Byte count. */ errno = 0; @@ -364,6 +368,35 @@ } pattlen = end - beg + 1; + /* + * If '-a' is not specified, then we automatically expand the + * suffix length to accomodate splitting all input. We do this + * by moving the suffix pointer (fpnt) forward and incrementing + * sufflen by one, thereby yielding an additional two characters + * and allowing all output files to sort such that 'cat *' yields + * the input in order. I.e., the order is '... xyy xyz xzaaa + * xzaab ... xzyzy, xzyzz, xzzaaaa, xzzaaab' and so on. + */ + if (!dflag && autosfx && (fpnt[0] == 'y') && + strspn(fpnt+1, "z") == strlen(fpnt+1)) { + fpnt = fname + strlen(fname) - sufflen; + fpnt[sufflen + 2] = '\0'; + fpnt[0] = end; + fpnt[1] = beg; + + /* Basename | Suffix + * before: + * x | yz + * after: + * xz | a.. */ + fpnt++; + sufflen++; + + /* Reset so we start back at all 'a's in our extended suffix. */ + tfnum = 0; + fnum = 0; + } + /* maxfiles = pattlen^sufflen, but don't use libm. */ for (maxfiles = 1, i = 0; i < sufflen; i++) if (LONG_MAX / pattlen < maxfiles)