From a64133250c9edd078cabc81883b7878abee6924b Mon Sep 17 00:00:00 2001 From: John Kerl Date: Sat, 6 Aug 2022 23:10:09 -0400 Subject: [PATCH] Fix natsort of empty strings; support mlr sort -rt same as -tr (#1068) * mlr sort -rt == mlrt sort -tr * fix natsort of empty strings --- docs/src/manpage.md | 4 ++-- docs/src/manpage.txt | 4 ++-- docs/src/online-help.md | 2 +- docs/src/reference-verbs.md | 2 +- internal/pkg/mlrval/mlrval_sort.go | 12 +++++++++- internal/pkg/transformers/sort.go | 24 ++++++++++++++----- man/manpage.txt | 4 ++-- man/mlr.1 | 6 ++--- test/cases/cli-help/0001/expout | 2 +- test/cases/verb-sort/0024/expout | 1 + test/cases/verb-sort/0025/expout | 1 + test/cases/verb-sort/0026/cmd | 1 + test/cases/verb-sort/0026/experr | 0 test/cases/verb-sort/0026/expout | 37 ++++++++++++++++++++++++++++++ test/input/natural-sort.csv | 1 + 15 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 test/cases/verb-sort/0026/cmd create mode 100644 test/cases/verb-sort/0026/experr create mode 100644 test/cases/verb-sort/0026/expout diff --git a/docs/src/manpage.md b/docs/src/manpage.md index db32ede54..9fe4d191f 100644 --- a/docs/src/manpage.md +++ b/docs/src/manpage.md @@ -1751,7 +1751,7 @@ VERBS -nf {comma-separated field names} Same as -n -nr {comma-separated field names} Numerical descending; nulls sort first -t {comma-separated field names} Natural ascending - -tr {comma-separated field names} Natural descending + -tr|-rt {comma-separated field names} Natural descending -h|--help Show this message. Example: @@ -3272,5 +3272,5 @@ SEE ALSO - 2022-08-01 MILLER(1) + 2022-08-07 MILLER(1) diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index f3899f091..e200a8696 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -1730,7 +1730,7 @@ VERBS -nf {comma-separated field names} Same as -n -nr {comma-separated field names} Numerical descending; nulls sort first -t {comma-separated field names} Natural ascending - -tr {comma-separated field names} Natural descending + -tr|-rt {comma-separated field names} Natural descending -h|--help Show this message. Example: @@ -3251,4 +3251,4 @@ SEE ALSO - 2022-08-01 MILLER(1) + 2022-08-07 MILLER(1) diff --git a/docs/src/online-help.md b/docs/src/online-help.md index a9e7d9d72..08111629d 100644 --- a/docs/src/online-help.md +++ b/docs/src/online-help.md @@ -213,7 +213,7 @@ Options: -nf {comma-separated field names} Same as -n -nr {comma-separated field names} Numerical descending; nulls sort first -t {comma-separated field names} Natural ascending --tr {comma-separated field names} Natural descending +-tr|-rt {comma-separated field names} Natural descending -h|--help Show this message. Example: diff --git a/docs/src/reference-verbs.md b/docs/src/reference-verbs.md index 3e2b3dcbb..c9dab6202 100644 --- a/docs/src/reference-verbs.md +++ b/docs/src/reference-verbs.md @@ -2846,7 +2846,7 @@ Options: -nf {comma-separated field names} Same as -n -nr {comma-separated field names} Numerical descending; nulls sort first -t {comma-separated field names} Natural ascending --tr {comma-separated field names} Natural descending +-tr|-rt {comma-separated field names} Natural descending -h|--help Show this message. Example: diff --git a/internal/pkg/mlrval/mlrval_sort.go b/internal/pkg/mlrval/mlrval_sort.go index ab7fa0bb3..75795b999 100644 --- a/internal/pkg/mlrval/mlrval_sort.go +++ b/internal/pkg/mlrval/mlrval_sort.go @@ -80,7 +80,17 @@ func NaturalAscendingComparator(input1, input2 *Mlrval) int { sb := input2.String() if sa == sb { return 0 - } else if natsort.Compare(input1.String(), input2.String()) { + } + + // natsort.Compare puts empty strings in random places + if sa == "" { + return 1 + } + if sb == "" { + return -1 + } + + if natsort.Compare(input1.String(), input2.String()) { return 1 } else { return -1 diff --git a/internal/pkg/transformers/sort.go b/internal/pkg/transformers/sort.go index ddf5bd1a8..5f559ec69 100644 --- a/internal/pkg/transformers/sort.go +++ b/internal/pkg/transformers/sort.go @@ -83,7 +83,7 @@ func transformerSortUsage( fmt.Fprintf(o, "-nf {comma-separated field names} Same as -n\n") fmt.Fprintf(o, "-nr {comma-separated field names} Numerical descending; nulls sort first\n") fmt.Fprintf(o, "-t {comma-separated field names} Natural ascending\n") - fmt.Fprintf(o, "-tr {comma-separated field names} Natural descending\n") + fmt.Fprintf(o, "-tr|-rt {comma-separated field names} Natural descending\n") fmt.Fprintf(o, "-h|--help Show this message.\n") fmt.Fprintf(o, "\n") fmt.Fprintf(o, "Example:\n") @@ -162,7 +162,6 @@ func transformerSortParseCLI( comparatorFuncs = append(comparatorFuncs, mlrval.NaturalAscendingComparator) } } else { - subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc) for _, item := range subList { groupByFieldNames = append(groupByFieldNames, item) @@ -171,10 +170,23 @@ func transformerSortParseCLI( } } else if opt == "-r" { - subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc) - for _, item := range subList { - groupByFieldNames = append(groupByFieldNames, item) - comparatorFuncs = append(comparatorFuncs, mlrval.LexicalDescendingComparator) + // See comments over "-n" -- similar hack. + cli.VerbCheckArgCount(verb, opt, args, argi, argc, 1) + if args[argi] == "-t" { + // Treat like "-rt" which is same as "-tr" + cli.VerbCheckArgCount(verb, args[argi], args, argi, argc, 1) + argi++ + subList := cli.VerbGetStringArrayArgOrDie(verb, "-tr", args, &argi, argc) + for _, item := range subList { + groupByFieldNames = append(groupByFieldNames, item) + comparatorFuncs = append(comparatorFuncs, mlrval.NaturalAscendingComparator) + } + } else { + subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc) + for _, item := range subList { + groupByFieldNames = append(groupByFieldNames, item) + comparatorFuncs = append(comparatorFuncs, mlrval.LexicalDescendingComparator) + } } } else if opt == "-n" { diff --git a/man/manpage.txt b/man/manpage.txt index f3899f091..e200a8696 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -1730,7 +1730,7 @@ VERBS -nf {comma-separated field names} Same as -n -nr {comma-separated field names} Numerical descending; nulls sort first -t {comma-separated field names} Natural ascending - -tr {comma-separated field names} Natural descending + -tr|-rt {comma-separated field names} Natural descending -h|--help Show this message. Example: @@ -3251,4 +3251,4 @@ SEE ALSO - 2022-08-01 MILLER(1) + 2022-08-07 MILLER(1) diff --git a/man/mlr.1 b/man/mlr.1 index fcfb90a3e..488d4f4fb 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -2,12 +2,12 @@ .\" Title: mlr .\" Author: [see the "AUTHOR" section] .\" Generator: ./mkman.rb -.\" Date: 2022-08-01 +.\" Date: 2022-08-07 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "MILLER" "1" "2022-08-01" "\ \&" "\ \&" +.TH "MILLER" "1" "2022-08-07" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Portability definitions .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2181,7 +2181,7 @@ Options: -nf {comma-separated field names} Same as -n -nr {comma-separated field names} Numerical descending; nulls sort first -t {comma-separated field names} Natural ascending --tr {comma-separated field names} Natural descending +-tr|-rt {comma-separated field names} Natural descending -h|--help Show this message. Example: diff --git a/test/cases/cli-help/0001/expout b/test/cases/cli-help/0001/expout index 62102a765..a3cae902f 100644 --- a/test/cases/cli-help/0001/expout +++ b/test/cases/cli-help/0001/expout @@ -932,7 +932,7 @@ Options: -nf {comma-separated field names} Same as -n -nr {comma-separated field names} Numerical descending; nulls sort first -t {comma-separated field names} Natural ascending --tr {comma-separated field names} Natural descending +-tr|-rt {comma-separated field names} Natural descending -h|--help Show this message. Example: diff --git a/test/cases/verb-sort/0024/expout b/test/cases/verb-sort/0024/expout index 3ae9bdaed..7cd3c2ed0 100644 --- a/test/cases/verb-sort/0024/expout +++ b/test/cases/verb-sort/0024/expout @@ -1,4 +1,5 @@ n,name +36, 2,10X Radonius 4,20X Radonius 5,20X Radonius Prime diff --git a/test/cases/verb-sort/0025/expout b/test/cases/verb-sort/0025/expout index 684cec16a..f1ea03c80 100644 --- a/test/cases/verb-sort/0025/expout +++ b/test/cases/verb-sort/0025/expout @@ -34,3 +34,4 @@ n,name 5,20X Radonius Prime 4,20X Radonius 2,10X Radonius +36, diff --git a/test/cases/verb-sort/0026/cmd b/test/cases/verb-sort/0026/cmd new file mode 100644 index 000000000..cd930a949 --- /dev/null +++ b/test/cases/verb-sort/0026/cmd @@ -0,0 +1 @@ +mlr --csv sort -rt name test/input/natural-sort.csv diff --git a/test/cases/verb-sort/0026/experr b/test/cases/verb-sort/0026/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/verb-sort/0026/expout b/test/cases/verb-sort/0026/expout new file mode 100644 index 000000000..f1ea03c80 --- /dev/null +++ b/test/cases/verb-sort/0026/expout @@ -0,0 +1,37 @@ +n,name +27,Xiph Xlater 10000 +34,Xiph Xlater 5000 +28,Xiph Xlater 2000 +33,Xiph Xlater 500 +29,Xiph Xlater 300 +35,Xiph Xlater 58 +32,Xiph Xlater 50 +30,Xiph Xlater 40 +31,Xiph Xlater 5 +26,Callisto Morphamax 7000 +24,Callisto Morphamax 6000 SE2 +23,Callisto Morphamax 6000 SE +21,Callisto Morphamax 5000 +25,Callisto Morphamax 700 +22,Callisto Morphamax 600 +20,Callisto Morphamax 500 +19,Callisto Morphamax +15,Alpha 200 +13,Alpha 100 +17,Alpha 2A-8000 +18,Alpha 2A-900 +16,Alpha 2A +14,Alpha 2 +9,Allegia 500 Clasteron +11,Allegia 51 Clasteron +10,Allegia 50B Clasteron +8,Allegia 50 Clasteron +12,Allegia 6R Clasteron +1,1000X Radonius Maximus +3,200X Radonius +7,40X Radonius +6,30X Radonius +5,20X Radonius Prime +4,20X Radonius +2,10X Radonius +36, diff --git a/test/input/natural-sort.csv b/test/input/natural-sort.csv index 44f9aaa50..a996f0518 100644 --- a/test/input/natural-sort.csv +++ b/test/input/natural-sort.csv @@ -34,3 +34,4 @@ n,name 33,Xiph Xlater 500 34,Xiph Xlater 5000 35,Xiph Xlater 58 +36,