diff --git a/go/src/miller/cli/mlrcli_mappers.go b/go/src/miller/cli/mlrcli_mappers.go index c441e67b3..f8f61a05d 100644 --- a/go/src/miller/cli/mlrcli_mappers.go +++ b/go/src/miller/cli/mlrcli_mappers.go @@ -11,6 +11,7 @@ import ( // ---------------------------------------------------------------- var MAPPER_LOOKUP_TABLE = []mapping.MapperSetup{ + mappers.AltkvSetup, mappers.BootstrapSetup, mappers.CatSetup, mappers.CheckSetup, diff --git a/go/src/miller/mappers/altkv.go b/go/src/miller/mappers/altkv.go new file mode 100644 index 000000000..8def9f122 --- /dev/null +++ b/go/src/miller/mappers/altkv.go @@ -0,0 +1,121 @@ +package mappers + +import ( + "flag" + "fmt" + "os" + "strconv" + + "miller/clitypes" + "miller/mapping" + "miller/types" +) + +// ---------------------------------------------------------------- +var AltkvSetup = mapping.MapperSetup{ + Verb: "altkv", + ParseCLIFunc: mapperAltkvParseCLI, + IgnoresInput: false, +} + +func mapperAltkvParseCLI( + pargi *int, + argc int, + args []string, + errorHandling flag.ErrorHandling, // ContinueOnError or ExitOnError + _ *clitypes.TReaderOptions, + __ *clitypes.TWriterOptions, +) mapping.IRecordMapper { + + // Get the verb name from the current spot in the mlr command line + argi := *pargi + verb := args[argi] + argi++ + + // Parse local flags + flagSet := flag.NewFlagSet(verb, errorHandling) + + flagSet.Usage = func() { + ostream := os.Stderr + if errorHandling == flag.ContinueOnError { // help intentionally requested + ostream = os.Stdout + } + mapperAltkvUsage(ostream, args[0], verb, flagSet) + } + flagSet.Parse(args[argi:]) + if errorHandling == flag.ContinueOnError { // help intentionally requested + return nil + } + + // Find out how many flags were consumed by this verb and advance for the + // next verb + argi = len(args) - len(flagSet.Args()) + + mapper, _ := NewMapperAltkv() + + *pargi = argi + return mapper +} + +func mapperAltkvUsage( + o *os.File, + argv0 string, + verb string, + flagSet *flag.FlagSet, +) { + fmt.Fprintf(o, "Usage: %s %s {no options}\n", argv0, verb) + fmt.Fprintf(o, "Given fields with values of the form a,b,c,d,e,f emits a=b,c=d,e=f pairs.\n") + + flagSet.VisitAll(func(f *flag.Flag) { + fmt.Fprintf(o, " -%v (default %v) %v\n", f.Name, f.Value, f.Usage) // f.Name, f.Value + }) +} + +// ---------------------------------------------------------------- +type MapperAltkv struct { +} + +func NewMapperAltkv() (*MapperAltkv, error) { + this := &MapperAltkv{} + return this, nil +} + +// ---------------------------------------------------------------- +func (this *MapperAltkv) Map( + inrecAndContext *types.RecordAndContext, + outputChannel chan<- *types.RecordAndContext, +) { + inrec := inrecAndContext.Record + if inrec != nil { // not end of record stream + newrec := types.NewMlrmapAsRecord() + outputFieldNumber := 1 + + fmt.Printf("\n"); + for pe := inrec.Head; pe != nil; /* increment in loop body */ { + if pe.Next != nil { // Not at end of record with odd-numbered field count + key := pe.Value.String() + value := pe.Next.Value + // Transferring ownership from old record to new record; no copy needed + newrec.PutReference(&key, value) + } else { // At end of record with odd-numbered field count + key := strconv.Itoa(outputFieldNumber) + value := pe.Value + // Transferring ownership from old record to new record; no copy needed + newrec.PutReference(&key, value) + } + outputFieldNumber++ + + pe = pe.Next + if pe == nil { + break + } + pe = pe.Next + } + fmt.Printf("\n"); + + outputChannel <- types.NewRecordAndContext(newrec, &inrecAndContext.Context) + + } else { // end of record stream + outputChannel <- inrecAndContext + } +} diff --git a/go/todo.txt b/go/todo.txt index 9e62b0cff..b97b46f56 100644 --- a/go/todo.txt +++ b/go/todo.txt @@ -3,6 +3,11 @@ TOP OF LIST: * UDFs * local vars w/ typing +* Check for "Options:" in all mappers + +* default ifs/ofs to space not comma for nidx. & what else did i miss? + +* sliding-window averages (C + Go) * some more verbs o altkv decimate having-fields remove-empty-columns reorder diff --git a/go/u/try-help.out b/go/u/try-help.out index 68b34f035..28cb42520 100644 --- a/go/u/try-help.out +++ b/go/u/try-help.out @@ -1,3 +1,7 @@ +================================================================ +Usage: ./mlr altkv {no options} +Given fields with values of the form a,b,c,d,e,f emits a=b,c=d,e=f pairs. + ================================================================ Usage: ./mlr bootstrap [options] Emits an n-sample, with replacement, of the input records. diff --git a/go/u/try-verbs b/go/u/try-verbs index 953ca6362..d62379c62 100755 --- a/go/u/try-verbs +++ b/go/u/try-verbs @@ -75,3 +75,6 @@ run_mlr --opprint --from u/s.dkvp grep -i -v PAN run_mlr --from u/s.dkvp skip-trivial-records run_mlr --from u/skip-trivial-records.dkvp skip-trivial-records + +echo 'a,b,c,d,e,f' | run_mlr --inidx --ifs comma altkv +echo 'a,b,c,d,e,f,g' | run_mlr --inidx --ifs comma altkv diff --git a/go/u/try-verbs.out b/go/u/try-verbs.out index fae003cf5..4026d9723 100644 --- a/go/u/try-verbs.out +++ b/go/u/try-verbs.out @@ -523,3 +523,15 @@ a=eks,b=wye,i=4,x=0.38139939387114097,y=0.13418874328430463 mlr --from u/skip-trivial-records.dkvp skip-trivial-records a=1,b=2 c=4,d= + +---------------------------------------------------------------- +mlr --inidx --ifs comma altkv + + +a=b,c=d,e=f + +---------------------------------------------------------------- +mlr --inidx --ifs comma altkv + + +a=b,c=d,e=f,4=g diff --git a/go/verbs-to-do b/go/verbs-to-do new file mode 100755 index 000000000..31f822bdf --- /dev/null +++ b/go/verbs-to-do @@ -0,0 +1,3 @@ +#!/bin/bash + +diff <(mlr -L) <(../c/mlr -L) | grep '>' | nf | cat -n