Add -d, -f and -i flags to sort(1)
Here's the patch with updated manpage and usage().
This commit is contained in:
parent
ae52820891
commit
fad1d35357
8
sort.1
8
sort.1
|
@ -6,7 +6,7 @@
|
||||||
.Nd sort lines
|
.Nd sort lines
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl Cbcmnru
|
.Op Fl Cbcdfimnru
|
||||||
.Op Fl o Ar outfile
|
.Op Fl o Ar outfile
|
||||||
.Op Fl t Ar delim
|
.Op Fl t Ar delim
|
||||||
.Op Fl k Ar key ...
|
.Op Fl k Ar key ...
|
||||||
|
@ -35,6 +35,12 @@ The same as
|
||||||
.Fl C
|
.Fl C
|
||||||
except that when disorder is detected, a message is written to stderr
|
except that when disorder is detected, a message is written to stderr
|
||||||
indicating the location of the disorder.
|
indicating the location of the disorder.
|
||||||
|
.It Fl d
|
||||||
|
Skip non-whitespace and non-alphanumeric characters.
|
||||||
|
.It Fl f
|
||||||
|
Ignore letter case when sorting.
|
||||||
|
.It FL i
|
||||||
|
Skip non-printable characters.
|
||||||
.It Fl k Ar key
|
.It Fl k Ar key
|
||||||
Specify a key definition of the form
|
Specify a key definition of the form
|
||||||
.Sm off
|
.Sm off
|
||||||
|
|
63
sort.c
63
sort.c
|
@ -23,6 +23,9 @@ enum {
|
||||||
MOD_STARTB = 1 << 1,
|
MOD_STARTB = 1 << 1,
|
||||||
MOD_ENDB = 1 << 2,
|
MOD_ENDB = 1 << 2,
|
||||||
MOD_R = 1 << 3,
|
MOD_R = 1 << 3,
|
||||||
|
MOD_D = 1 << 4,
|
||||||
|
MOD_F = 1 << 5,
|
||||||
|
MOD_I = 1 << 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
static TAILQ_HEAD(kdhead, keydef) kdhead = TAILQ_HEAD_INITIALIZER(kdhead);
|
static TAILQ_HEAD(kdhead, keydef) kdhead = TAILQ_HEAD_INITIALIZER(kdhead);
|
||||||
|
@ -115,6 +118,44 @@ columns(char *line, const struct keydef *kd, char **col, size_t *colsiz)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
skipmodcmp(const char *s1, const char *s2, int flags)
|
||||||
|
{
|
||||||
|
Rune r1, r2;
|
||||||
|
|
||||||
|
do {
|
||||||
|
s1 += chartorune(&r1, s1);
|
||||||
|
s2 += chartorune(&r2, s2);
|
||||||
|
|
||||||
|
if (flags & MOD_D && flags & MOD_I) {
|
||||||
|
while (*s1 && ((!isblankrune(r1) && !isalnumrune(r1)) ||
|
||||||
|
(!isprintrune(r1))))
|
||||||
|
s1 += chartorune(&r1, s1);
|
||||||
|
while (*s2 && ((!isblankrune(r2) && !isalnumrune(r2)) ||
|
||||||
|
(!isprintrune(r2))))
|
||||||
|
s2 += chartorune(&r2, s2);
|
||||||
|
}
|
||||||
|
else if (flags & MOD_D) {
|
||||||
|
while (*s1 && !isblankrune(r1) && !isalnumrune(r1))
|
||||||
|
s1 += chartorune(&r1, s1);
|
||||||
|
while (*s2 && !isblankrune(r2) && !isalnumrune(r2))
|
||||||
|
s2 += chartorune(&r2, s2);
|
||||||
|
}
|
||||||
|
else if (flags & MOD_I) {
|
||||||
|
while (*s1 && !isprintrune(r1))
|
||||||
|
s1 += chartorune(&r1, s1);
|
||||||
|
while (*s2 && !isprintrune(r2))
|
||||||
|
s2 += chartorune(&r2, s2);
|
||||||
|
}
|
||||||
|
if (flags & MOD_F) {
|
||||||
|
r1 = toupperrune(r1);
|
||||||
|
r2 = toupperrune(r2);
|
||||||
|
}
|
||||||
|
} while (r1 && r1 == r2);
|
||||||
|
|
||||||
|
return r1 - r2;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
linecmp(const char **a, const char **b)
|
linecmp(const char **a, const char **b)
|
||||||
{
|
{
|
||||||
|
@ -135,6 +176,8 @@ linecmp(const char **a, const char **b)
|
||||||
x = strtold(col1, NULL);
|
x = strtold(col1, NULL);
|
||||||
y = strtold(col2, NULL);
|
y = strtold(col2, NULL);
|
||||||
res = (x < y) ? -1 : (x > y);
|
res = (x < y) ? -1 : (x > y);
|
||||||
|
} else if (kd->flags & (MOD_D | MOD_F | MOD_I)) {
|
||||||
|
res = skipmodcmp(col1, col2, kd->flags);
|
||||||
} else {
|
} else {
|
||||||
res = strcmp(col1, col2);
|
res = strcmp(col1, col2);
|
||||||
}
|
}
|
||||||
|
@ -178,6 +221,15 @@ parse_flags(char **s, int *flags, int bflag)
|
||||||
case 'b':
|
case 'b':
|
||||||
*flags |= bflag;
|
*flags |= bflag;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
*flags |= MOD_D;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
*flags |= MOD_F;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
*flags |= MOD_I;
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
*flags |= MOD_N;
|
*flags |= MOD_N;
|
||||||
break;
|
break;
|
||||||
|
@ -240,7 +292,7 @@ addkeydef(char *kdstr, int flags)
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
enprintf(2, "usage: %s [-Cbcmnru] [-o outfile] [-t delim] "
|
enprintf(2, "usage: %s [-Cbcdfimnru] [-o outfile] [-t delim] "
|
||||||
"[-k def]... [file ...]\n", argv0);
|
"[-k def]... [file ...]\n", argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +315,15 @@ main(int argc, char *argv[])
|
||||||
case 'c':
|
case 'c':
|
||||||
cflag = 1;
|
cflag = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
global_flags |= MOD_D;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
global_flags |= MOD_F;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
global_flags |= MOD_I;
|
||||||
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
addkeydef(EARGF(usage()), global_flags);
|
addkeydef(EARGF(usage()), global_flags);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user