miller/go/src/cli/mlrcli_usage.go

526 lines
28 KiB
Go

package cli
import (
"fmt"
"os"
"miller/src/lib"
"miller/src/cliutil"
"miller/src/version"
)
// ----------------------------------------------------------------
func mainUsageShort() {
fmt.Fprintf(os.Stderr, "Please run \"%s --help\" for detailed usage information.\n", lib.MlrExeName())
os.Exit(1)
}
// ----------------------------------------------------------------
// The mainUsageLong() function is split out into subroutines in support of the
// manpage autogenerator.
func mainUsageLong(o *os.File, argv0 string) {
mainUsageSynopsis(o, argv0)
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "COMMAND-LINE-SYNTAX EXAMPLES:\n")
mainUsageExamples(o, argv0, " ")
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "DATA-FORMAT EXAMPLES:\n")
mainUsageDataFormatExamples(o, argv0)
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "HELP OPTIONS:\n")
mainUsageHelpOptions(o, argv0)
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "CUSTOMIZATION VIA .MLRRC:\n")
mainUsageMlrrc(o, argv0)
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "VERBS:\n")
listAllVerbs(o, " ")
fmt.Fprintf(o, "\n")
// fmt.Fprintf(o, "FUNCTIONS FOR THE FILTER AND PUT VERBS:\n");
// mainUsageFunctions(o, argv0, " ");
// fmt.Fprintf(o, "\n");
fmt.Fprintf(o, "DATA-FORMAT OPTIONS, FOR INPUT, OUTPUT, OR BOTH:\n")
mainUsageDataFormatOptions(o, argv0)
fmt.Fprintf(o, "\n")
// fmt.Fprintf(o, "COMMENTS IN DATA:\N");
// mainUsageCommentsInData(o, argv0);
// fmt.Fprintf(o, "\n");
//
fmt.Fprintf(o, "FORMAT-CONVERSION KEYSTROKE-SAVER OPTIONS:\n")
mainUsageFormatConversionKeystrokeSaverOptions(o, argv0)
fmt.Fprintf(o, "\n")
// fmt.Fprintf(o, "COMPRESSED-DATA OPTIONS:\N");
// mainUsageCompressedDataOptions(o, argv0);
// fmt.Fprintf(o, "\n");
//
// fmt.Fprintf(o, "SEPARATOR OPTIONS:\n");
// mainUsageSeparatorOptions(o, argv0);
// fmt.Fprintf(o, "\n");
//
// fmt.Fprintf(o, "RELEVANT TO CSV/CSV-LITE INPUT ONLY:\n");
// mainUsageCsvOptions(o, argv0);
// fmt.Fprintf(o, "\n");
//
// fmt.Fprintf(o, "DOUBLE-QUOTING FOR CSV OUTPUT:\n");
// mainUsageDoubleQuoting(o, argv0);
// fmt.Fprintf(o, "\n");
//
// fmt.Fprintf(o, "NUMERICAL FORMATTING:\n");
// mainUsageNumericalFormatting(o, argv0);
// fmt.Fprintf(o, "\n");
//
// fmt.Fprintf(o, "OTHER OPTIONS:\n");
// mainUsageOtherOptions(o, argv0);
// fmt.Fprintf(o, "\n");
//
fmt.Fprintf(o, "THEN-CHAINING:\n")
mainUsageThenChaining(o, argv0)
fmt.Fprintf(o, "\n")
// fmt.Fprintf(o, "AUXILIARY COMMANDS:\N");
// mainUsageAuxents(o, argv0);
// fmt.Fprintf(o, "\n");
//
fmt.Fprintf(o, "SEE ALSO:\n")
mainUsageSeeAlso(o, argv0)
}
func mainUsageSynopsis(o *os.File, argv0 string) {
fmt.Fprintf(o, "Usage: %s [I/O options] {verb} [verb-dependent options ...] {zero or more file names}\n", argv0)
}
func mainUsageExamples(o *os.File, argv0 string, leader string) {
fmt.Fprintf(o, "%s%s --csv cut -f hostname,uptime mydata.csv\n", leader, argv0)
fmt.Fprintf(o, "%s%s --tsv --rs lf filter '$status != \"down\" && $upsec >= 10000' *.tsv\n", leader, argv0)
fmt.Fprintf(o, "%s%s --nidx put '$sum = $7 < 0.0 ? 3.5 : $7 + 2.1*$8' *.dat\n", leader, argv0)
fmt.Fprintf(o, "%sgrep -v '^#' /etc/group | %s --ifs : --nidx --opprint label group,pass,gid,member then sort -f group\n", leader, argv0)
fmt.Fprintf(o, "%s%s join -j account_id -f accounts.dat then group-by account_name balances.dat\n", leader, argv0)
fmt.Fprintf(o, "%s%s --json put '$attr = sub($attr, \"([0-9]+)_([0-9]+)_.*\", \"\\1:\\2\")' data/*.json\n", leader, argv0)
fmt.Fprintf(o, "%s%s stats1 -a min,mean,max,p10,p50,p90 -f flag,u,v data/*\n", leader, argv0)
fmt.Fprintf(o, "%s%s stats2 -a linreg-pca -f u,v -g shape data/*\n", leader, argv0)
fmt.Fprintf(o, "%s%s put -q '@sum[$a][$b] += $x; end {emit @sum, \"a\", \"b\"}' data/*\n", leader, argv0)
fmt.Fprintf(o, "%s%s --from estimates.tbl put '\n", leader, argv0)
fmt.Fprintf(o, " for (k,v in $*) {\n")
fmt.Fprintf(o, " if (is_numeric(v) && k =~ \"^[t-z].*$\") {\n")
fmt.Fprintf(o, " $sum += v; $count += 1\n")
fmt.Fprintf(o, " }\n")
fmt.Fprintf(o, " }\n")
fmt.Fprintf(o, " $mean = $sum / $count # no assignment if count unset'\n")
fmt.Fprintf(o, "%s%s --from infile.dat put -f analyze.mlr\n", leader, argv0)
fmt.Fprintf(o, "%s%s --from infile.dat put 'tee > \"./taps/data-\".$a.\"-\".$b, $*'\n", leader, argv0)
fmt.Fprintf(o, "%s%s --from infile.dat put 'tee | \"gzip > ./taps/data-\".$a.\"-\".$b.\".gz\", $*'\n", leader, argv0)
fmt.Fprintf(o, "%s%s --from infile.dat put -q '@v=$*; dump | \"jq .[]\"'\n", leader, argv0)
fmt.Fprintf(o, "%s%s --from infile.dat put '(NR %% 1000 == 0) { print > os.Stderr, \"Checkpoint \".NR}'\n",
leader, argv0)
}
func mainUsageHelpOptions(o *os.File, argv0 string) {
fmt.Fprintf(o, " -h or --help Show this message.\n")
fmt.Fprintf(o, " --version Show the software version.\n")
fmt.Fprintf(o, " {verb name} --help Show verb-specific help.\n")
fmt.Fprintf(o, " --help-all-verbs Show help on all verbs.\n")
fmt.Fprintf(o, " -l or --list-all-verbs List only verb names.\n")
fmt.Fprintf(o, " -L List only verb names, one per line.\n")
fmt.Fprintf(o, " -f or --help-all-functions Show help on all built-in functions.\n")
fmt.Fprintf(o, " -F Show a bare listing of built-in functions by name.\n")
fmt.Fprintf(o, " -k or --help-all-keywords Show help on all keywords.\n")
fmt.Fprintf(o, " -K Show a bare listing of keywords by name.\n")
}
func mainUsageMlrrc(o *os.File, argv0 string) {
fmt.Fprintf(o, "You can set up personal defaults via a $HOME/.mlrrc and/or ./.mlrrc.\n")
fmt.Fprintf(o, "For example, if you usually process CSV, then you can put \"--csv\" in your .mlrrc file\n")
fmt.Fprintf(o, "and that will be the default input/output format unless otherwise specified on the command line.\n")
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "The .mlrrc file format is one \"--flag\" or \"--option value\" per line, with the leading \"--\" optional.\n")
fmt.Fprintf(o, "Hash-style comments and blank lines are ignored.\n")
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "Sample .mlrrc:\n")
fmt.Fprintf(o, "# Input and output formats are CSV by default (unless otherwise specified\n")
fmt.Fprintf(o, "# on the mlr command line):\n")
fmt.Fprintf(o, "csv\n")
fmt.Fprintf(o, "# These are no-ops for CSV, but when I do use JSON output, I want these\n")
fmt.Fprintf(o, "# pretty-printing options to be used:\n")
fmt.Fprintf(o, "jvstack\n")
fmt.Fprintf(o, "jlistwrap\n")
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "How to specify location of .mlrrc:\n")
fmt.Fprintf(o, "* If $MLRRC is set:\n")
fmt.Fprintf(o, " o If its value is \"__none__\" then no .mlrrc files are processed.\n")
fmt.Fprintf(o, " o Otherwise, its value (as a filename) is loaded and processed. If there are syntax\n")
fmt.Fprintf(o, " errors, they abort mlr with a usage message (as if you had mistyped something on the\n")
fmt.Fprintf(o, " command line). If the file can't be loaded at all, though, it is silently skipped.\n")
fmt.Fprintf(o, " o Any .mlrrc in your home directory or current directory is ignored whenever $MLRRC is\n")
fmt.Fprintf(o, " set in the environment.\n")
fmt.Fprintf(o, "* Otherwise:\n")
fmt.Fprintf(o, " o If $HOME/.mlrrc exists, it's then processed as above.\n")
fmt.Fprintf(o, " o If ./.mlrrc exists, it's then also processed as above.\n")
fmt.Fprintf(o, " (I.e. current-directory .mlrrc defaults are stacked over home-directory .mlrrc defaults.)\n")
fmt.Fprintf(o, "\n")
fmt.Fprintf(o, "See also:\n")
fmt.Fprintf(o, "https://miller.readthedocs.io/en/latest/customization.html\n")
}
//func mainUsageFunctions(o *os.File, argv0 string, char* leader) {
// fmgr_t* pfmgr = fmgr_alloc();
// fmgr_list_functions(pfmgr, o, leader);
// fmgr_free(pfmgr, nil);
// fmt.Fprintf(o, "\n");
// fmt.Fprintf(o, "Please use \"%s --help-function {function name}\" for function-specific help.\n", argv0);
//}
func mainUsageDataFormatExamples(o *os.File, argv0 string) {
fmt.Fprintf(o,
` DKVP: delimited key-value pairs (Miller default format)
+---------------------+
| apple=1,bat=2,cog=3 | Record 1: "apple" => "1", "bat" => "2", "cog" => "3"
| dish=7,egg=8,flint | Record 2: "dish" => "7", "egg" => "8", "3" => "flint"
+---------------------+
NIDX: implicitly numerically indexed (Unix-toolkit style)
+---------------------+
| the quick brown | Record 1: "1" => "the", "2" => "quick", "3" => "brown"
| fox jumped | Record 2: "1" => "fox", "2" => "jumped"
+---------------------+
CSV/CSV-lite: comma-separated values with separate header line
+---------------------+
| apple,bat,cog |
| 1,2,3 | Record 1: "apple => "1", "bat" => "2", "cog" => "3"
| 4,5,6 | Record 2: "apple" => "4", "bat" => "5", "cog" => "6"
+---------------------+
Tabular JSON: nested objects are supported, although arrays within them are not:
+---------------------+
| { |
| "apple": 1, | Record 1: "apple" => "1", "bat" => "2", "cog" => "3"
| "bat": 2, |
| "cog": 3 |
| } |
| { |
| "dish": { | Record 2: "dish:egg" => "7", "dish:flint" => "8", "garlic" => ""
| "egg": 7, |
| "flint": 8 |
| }, |
| "garlic": "" |
| } |
+---------------------+
PPRINT: pretty-printed tabular
+---------------------+
| apple bat cog |
| 1 2 3 | Record 1: "apple => "1", "bat" => "2", "cog" => "3"
| 4 5 6 | Record 2: "apple" => "4", "bat" => "5", "cog" => "6"
+---------------------+
XTAB: pretty-printed transposed tabular
+---------------------+
| apple 1 | Record 1: "apple" => "1", "bat" => "2", "cog" => "3"
| bat 2 |
| cog 3 |
| |
| dish 7 | Record 2: "dish" => "7", "egg" => "8"
| egg 8 |
+---------------------+
Markdown tabular (supported for output only):
+-----------------------+
| | apple | bat | cog | |
| | --- | --- | --- | |
| | 1 | 2 | 3 | | Record 1: "apple => "1", "bat" => "2", "cog" => "3"
| | 4 | 5 | 6 | | Record 2: "apple" => "4", "bat" => "5", "cog" => "6"
+-----------------------+
`)
}
func mainUsageDataFormatOptions(o *os.File, argv0 string) {
fmt.Fprintf(o,
`
--idkvp --odkvp --dkvp Delimited key-value pairs, e.g "a=1,b=2"
(this is Miller's default format).
--inidx --onidx --nidx Implicitly-integer-indexed fields
(Unix-toolkit style).
-T Synonymous with "--nidx --fs tab".
--icsv --ocsv --csv Comma-separated value (or tab-separated
with --fs tab, etc.)
--itsv --otsv --tsv Keystroke-savers for "--icsv --ifs tab",
"--ocsv --ofs tab", "--csv --fs tab".
--iasv --oasv --asv Similar but using ASCII FS %s and RS %s\n",
--iusv --ousv --usv Similar but using Unicode FS %s\n",
and RS %s\n",
--icsvlite --ocsvlite --csvlite Comma-separated value (or tab-separated
with --fs tab, etc.). The 'lite' CSV does not handle
RFC-CSV double-quoting rules; is slightly faster;
and handles heterogeneity in the input stream via
empty newline followed by new header line. See also
http://johnkerl.org/miller/doc/file-formats.html#CSV/TSV/etc.
--itsvlite --otsvlite --tsvlite Keystroke-savers for "--icsvlite --ifs tab",
"--ocsvlite --ofs tab", "--csvlite --fs tab".
-t Synonymous with --tsvlite.
--iasvlite --oasvlite --asvlite Similar to --itsvlite et al. but using ASCII FS %s and RS %s\n",
--iusvlite --ousvlite --usvlite Similar to --itsvlite et al. but using Unicode FS %s\n",
and RS %s\n",
--ipprint --opprint --pprint Pretty-printed tabular (produces no
output until all input is in).
--right Right-justifies all fields for PPRINT output.
--barred Prints a border around PPRINT output
(only available for output).
--omd Markdown-tabular (only available for output).
--ixtab --oxtab --xtab Pretty-printed vertical-tabular.
--xvright Right-justifies values for XTAB format.
--ijson --ojson --json JSON tabular: sequence or list of one-level
maps: {...}{...} or [{...},{...}].
--json-map-arrays-on-input JSON arrays are unmillerable. --json-map-arrays-on-input
--json-skip-arrays-on-input is the default: arrays are converted to integer-indexed
--json-fatal-arrays-on-input maps. The other two options cause them to be skipped, or
to be treated as errors. Please use the jq tool for full
JSON (pre)processing.
--jvstack Put one key-value pair per line for JSON output.
--no-jvstack Put objects/arrays all on one line for JSON output.
--jsonx --ojsonx Keystroke-savers for --json --jvstack
--jsonx --ojsonx and --ojson --jvstack, respectively.
--jlistwrap Wrap JSON output in outermost [ ].
--jknquoteint Do not quote non-string map keys in JSON output.
--jvquoteall Quote map values in JSON output, even if they're
numeric.
--oflatsep {string} Separator for flattening multi-level JSON keys,
e.g. '{"a":{"b":3}}' becomes a:b => 3 for
non-JSON formats. Defaults to %s.\n",
-p is a keystroke-saver for --nidx --fs space --repifs
Examples: --csv for CSV-formatted input and output; --idkvp --opprint for
DKVP-formatted input and pretty-printed output.
Please use --iformat1 --oformat2 rather than --format1 --oformat2.
The latter sets up input and output flags for format1, not all of which
are overridden in all cases by setting output format to format2.`,
cliutil.ASV_FS_FOR_HELP,
cliutil.ASV_RS_FOR_HELP,
cliutil.USV_FS_FOR_HELP,
cliutil.USV_RS_FOR_HELP,
cliutil.ASV_FS_FOR_HELP,
cliutil.ASV_RS_FOR_HELP,
cliutil.USV_FS_FOR_HELP,
cliutil.USV_RS_FOR_HELP,
cliutil.DEFAULT_JSON_FLATTEN_SEPARATOR,
)
fmt.Println()
fmt.Println()
}
//func mainUsageCommentsInData(o *os.File, argv0 string) {
// fmt.Fprintf(o, " --skip-comments Ignore commented lines (prefixed by \"%s\")\n",
// DEFAULT_COMMENT_STRING);
// fmt.Fprintf(o, " within the input.\n");
// fmt.Fprintf(o, " --skip-comments-with {string} Ignore commented lines within input, with\n");
// fmt.Fprintf(o, " specified prefix.\n");
// fmt.Fprintf(o, " --pass-comments Immediately print commented lines (prefixed by \"%s\")\n",
// DEFAULT_COMMENT_STRING);
// fmt.Fprintf(o, " within the input.\n");
// fmt.Fprintf(o, " --pass-comments-with {string} Immediately print commented lines within input, with\n");
// fmt.Fprintf(o, " specified prefix.\n");
// fmt.Fprintf(o, "Notes:\n");
// fmt.Fprintf(o, "* Comments are only honored at the start of a line.\n");
// fmt.Fprintf(o, "* In the absence of any of the above four options, comments are data like\n");
// fmt.Fprintf(o, " any other text.\n");
// fmt.Fprintf(o, "* When pass-comments is used, comment lines are written to standard output\n");
// fmt.Fprintf(o, " immediately upon being read; they are not part of the record stream.\n");
// fmt.Fprintf(o, " Results may be counterintuitive. A suggestion is to place comments at the\n");
// fmt.Fprintf(o, " start of data files.\n");
//}
func mainUsageFormatConversionKeystrokeSaverOptions(o *os.File, argv0 string) {
fmt.Fprintf(o, "As keystroke-savers for format-conversion you may use the following:\n")
fmt.Fprintf(o, " --c2t --c2d --c2n --c2j --c2x --c2p --c2m\n")
fmt.Fprintf(o, " --t2c --t2d --t2n --t2j --t2x --t2p --t2m\n")
fmt.Fprintf(o, " --d2c --d2t --d2n --d2j --d2x --d2p --d2m\n")
fmt.Fprintf(o, " --n2c --n2t --n2d --n2j --n2x --n2p --n2m\n")
fmt.Fprintf(o, " --j2c --j2t --j2d --j2n --j2x --j2p --j2m\n")
fmt.Fprintf(o, " --x2c --x2t --x2d --x2n --x2j --x2p --x2m\n")
fmt.Fprintf(o, " --p2c --p2t --p2d --p2n --p2j --p2x --p2m\n")
fmt.Fprintf(o, "The letters c t d n j x p m refer to formats CSV, TSV, DKVP, NIDX, JSON, XTAB,\n")
fmt.Fprintf(o, "PPRINT, and markdown, respectively. Note that markdown format is available for\n")
fmt.Fprintf(o, "output only.\n")
}
//func mainUsageCompressedDataOptions(o *os.File, argv0 string) {
// fmt.Fprintf(o, " --prepipe {command} This allows Miller to handle compressed inputs. You can do\n");
// fmt.Fprintf(o, " without this for single input files, e.g. \"gunzip < myfile.csv.gz | %s ...\".\n",
// argv0);
// fmt.Fprintf(o, " However, when multiple input files are present, between-file separations are\n");
// fmt.Fprintf(o, " lost; also, the FILENAME variable doesn't iterate. Using --prepipe you can\n");
// fmt.Fprintf(o, " specify an action to be taken on each input file. This pre-pipe command must\n");
// fmt.Fprintf(o, " be able to read from standard input; it will be invoked with\n");
// fmt.Fprintf(o, " {command} < {filename}.\n");
// fmt.Fprintf(o, " Examples:\n");
// fmt.Fprintf(o, " %s --prepipe 'gunzip'\n", argv0);
// fmt.Fprintf(o, " %s --prepipe 'zcat -cf'\n", argv0);
// fmt.Fprintf(o, " %s --prepipe 'xz -cd'\n", argv0);
// fmt.Fprintf(o, " %s --prepipe cat\n", argv0);
// fmt.Fprintf(o, " Note that this feature is quite general and is not limited to decompression\n");
// fmt.Fprintf(o, " utilities. You can use it to apply per-file filters of your choice.\n");
// fmt.Fprintf(o, " For output compression (or other) utilities, simply pipe the output:\n");
// fmt.Fprintf(o, " %s ... | {your compression command}\n", argv0);
//}
//func mainUsageSeparatorOptions(o *os.File, argv0 string) {
// fmt.Fprintf(o, " --rs --irs --ors Record separators, e.g. 'lf' or '\\r\\n'\n");
// fmt.Fprintf(o, " --fs --ifs --ofs --repifs Field separators, e.g. comma\n");
// fmt.Fprintf(o, " --ps --ips --ops Pair separators, e.g. equals sign\n");
// fmt.Fprintf(o, "\n");
// fmt.Fprintf(o, " Notes about line endings:\n");
// fmt.Fprintf(o, " * Default line endings (--irs and --ors) are \"auto\" which means autodetect from\n");
// fmt.Fprintf(o, " the input file format, as long as the input file(s) have lines ending in either\n");
// fmt.Fprintf(o, " LF (also known as linefeed, '\\n', 0x0a, Unix-style) or CRLF (also known as\n");
// fmt.Fprintf(o, " carriage-return/linefeed pairs, '\\r\\n', 0x0d 0x0a, Windows style).\n");
// fmt.Fprintf(o, " * If both irs and ors are auto (which is the default) then LF input will lead to LF\n");
// fmt.Fprintf(o, " output and CRLF input will lead to CRLF output, regardless of the platform you're\n");
// fmt.Fprintf(o, " running on.\n");
// fmt.Fprintf(o, " * The line-ending autodetector triggers on the first line ending detected in the input\n");
// fmt.Fprintf(o, " stream. E.g. if you specify a CRLF-terminated file on the command line followed by an\n");
// fmt.Fprintf(o, " LF-terminated file then autodetected line endings will be CRLF.\n");
// fmt.Fprintf(o, " * If you use --ors {something else} with (default or explicitly specified) --irs auto\n");
// fmt.Fprintf(o, " then line endings are autodetected on input and set to what you specify on output.\n");
// fmt.Fprintf(o, " * If you use --irs {something else} with (default or explicitly specified) --ors auto\n");
// fmt.Fprintf(o, " then the output line endings used are LF on Unix/Linux/BSD/MacOSX, and CRLF on Windows.\n");
// fmt.Fprintf(o, "\n");
// fmt.Fprintf(o, " Notes about all other separators:\n");
// fmt.Fprintf(o, " * IPS/OPS are only used for DKVP and XTAB formats, since only in these formats\n");
// fmt.Fprintf(o, " do key-value pairs appear juxtaposed.\n");
// fmt.Fprintf(o, " * IRS/ORS are ignored for XTAB format. Nominally IFS and OFS are newlines;\n");
// fmt.Fprintf(o, " XTAB records are separated by two or more consecutive IFS/OFS -- i.e.\n");
// fmt.Fprintf(o, " a blank line. Everything above about --irs/--ors/--rs auto becomes --ifs/--ofs/--fs\n");
// fmt.Fprintf(o, " auto for XTAB format. (XTAB's default IFS/OFS are \"auto\".)\n");
// fmt.Fprintf(o, " * OFS must be single-character for PPRINT format. This is because it is used\n");
// fmt.Fprintf(o, " with repetition for alignment; multi-character separators would make\n");
// fmt.Fprintf(o, " alignment impossible.\n");
// fmt.Fprintf(o, " * OPS may be multi-character for XTAB format, in which case alignment is\n");
// fmt.Fprintf(o, " disabled.\n");
// fmt.Fprintf(o, " * TSV is simply CSV using tab as field separator (\"--fs tab\").\n");
// fmt.Fprintf(o, " * FS/PS are ignored for markdown format; RS is used.\n");
// fmt.Fprintf(o, " * All FS and PS options are ignored for JSON format, since they are not relevant\n");
// fmt.Fprintf(o, " to the JSON format.\n");
// fmt.Fprintf(o, " * You can specify separators in any of the following ways, shown by example:\n");
// fmt.Fprintf(o, " - Type them out, quoting as necessary for shell escapes, e.g.\n");
// fmt.Fprintf(o, " \"--fs '|' --ips :\"\n");
// fmt.Fprintf(o, " - C-style escape sequences, e.g. \"--rs '\\r\\n' --fs '\\t'\".\n");
// fmt.Fprintf(o, " - To avoid backslashing, you can use any of the following names:\n");
// fmt.Fprintf(o, " ");
// lhmss_t* pmap = get_desc_to_chars_map();
// for (lhmsse_t* pe = pmap.phead; pe != nil; pe = pe.pnext) {
// fmt.Fprintf(o, " %s", pe.key);
// }
// fmt.Fprintf(o, "\n");
// fmt.Fprintf(o, " * Default separators by format:\n");
// fmt.Fprintf(o, " %-12s %-8s %-8s %s\n", "File format", "RS", "FS", "PS");
// lhmss_t* default_rses = get_default_rses();
// lhmss_t* default_fses = get_default_fses();
// lhmss_t* default_pses = get_default_pses();
// for (lhmsse_t* pe = default_rses.phead; pe != nil; pe = pe.pnext) {
// char* filefmt = pe.key;
// char* rs = pe.value;
// char* fs = lhmss_get(default_fses, filefmt);
// char* ps = lhmss_get(default_pses, filefmt);
// fmt.Fprintf(o, " %-12s %-8s %-8s %s\n", filefmt, rebackslash(rs), rebackslash(fs), rebackslash(ps));
// }
//}
//func mainUsageCsvOptions(o *os.File, argv0 string) {
// fmt.Fprintf(o, " --implicit-csv-header Use 1,2,3,... as field labels, rather than from line 1\n");
// fmt.Fprintf(o, " of input files. Tip: combine with \"label\" to recreate\n");
// fmt.Fprintf(o, " missing headers.\n");
// fmt.Fprintf(o, " --allow-ragged-csv-input|--ragged If a data line has fewer fields than the header line,\n");
// fmt.Fprintf(o, " fill remaining keys with empty string. If a data line has more\n");
// fmt.Fprintf(o, " fields than the header line, use integer field labels as in\n");
// fmt.Fprintf(o, " the implicit-header case.\n");
// fmt.Fprintf(o, " --headerless-csv-output Print only CSV data lines.\n");
// fmt.Fprintf(o, " -N Keystroke-saver for --implicit-csv-header --headerless-csv-output.\n");
//}
//func mainUsageDoubleQuoting(o *os.File, argv0 string) {
// fmt.Fprintf(o, " --quote-all Wrap all fields in double quotes\n");
// fmt.Fprintf(o, " --quote-none Do not wrap any fields in double quotes, even if they have\n");
// fmt.Fprintf(o, " OFS or ORS in them\n");
// fmt.Fprintf(o, " --quote-minimal Wrap fields in double quotes only if they have OFS or ORS\n");
// fmt.Fprintf(o, " in them (default)\n");
// fmt.Fprintf(o, " --quote-numeric Wrap fields in double quotes only if they have numbers\n");
// fmt.Fprintf(o, " in them\n");
// fmt.Fprintf(o, " --quote-original Wrap fields in double quotes if and only if they were\n");
// fmt.Fprintf(o, " quoted on input. This isn't sticky for computed fields:\n");
// fmt.Fprintf(o, " e.g. if fields a and b were quoted on input and you do\n");
// fmt.Fprintf(o, " \"put '$c = $a . $b'\" then field c won't inherit a or b's\n");
// fmt.Fprintf(o, " was-quoted-on-input flag.\n");
//}
//func mainUsageNumericalFormatting(o *os.File, argv0 string) {
// fmt.Fprintf(o, " --ofmt {format} E.g. %%.18lf, %%.0lf. Please use sprintf-style codes for\n");
// fmt.Fprintf(o, " double-precision. Applies to verbs which compute new\n");
// fmt.Fprintf(o, " values, e.g. put, stats1, stats2. See also the fmtnum\n");
// fmt.Fprintf(o, " function within mlr put (mlr --help-all-functions).\n");
// fmt.Fprintf(o, " Defaults to %s.\n", DEFAULT_OFMT);
//}
//func mainUsageOtherOptions(o *os.File, argv0 string) {
// fmt.Fprintf(o, " --seed {n} with n of the form 12345678 or 0xcafefeed. For put/filter\n");
// fmt.Fprintf(o, " urand()/urandint()/urand32().\n");
// fmt.Fprintf(o, " --nr-progress-mod {m}, with m a positive integer: print filename and record\n");
// fmt.Fprintf(o, " count to os.Stderr every m input records.\n");
// fmt.Fprintf(o, " --from {filename} Use this to specify an input file before the verb(s),\n");
// fmt.Fprintf(o, " rather than after. May be used more than once. Example:\n");
// fmt.Fprintf(o, " \"%s --from a.dat --from b.dat cat\" is the same as\n", argv0);
// fmt.Fprintf(o, " \"%s cat a.dat b.dat\".\n", argv0);
// fmt.Fprintf(o, " -n Process no input files, nor standard input either. Useful\n");
// fmt.Fprintf(o, " for %s put with begin/end statements only. (Same as --from\n", argv0);
// fmt.Fprintf(o, " /dev/null.) Also useful in \"%s -n put -v '...'\" for\n", argv0);
// fmt.Fprintf(o, " analyzing abstract syntax trees (if that's your thing).\n");
// fmt.Fprintf(o, " -I Process files in-place. For each file name on the command\n");
// fmt.Fprintf(o, " line, output is written to a temp file in the same\n");
// fmt.Fprintf(o, " directory, which is then renamed over the original. Each\n");
// fmt.Fprintf(o, " file is processed in isolation: if the output format is\n");
// fmt.Fprintf(o, " CSV, CSV headers will be present in each output file;\n");
// fmt.Fprintf(o, " statistics are only over each file's own records; and so on.\n");
//}
func mainUsageThenChaining(o *os.File, argv0 string) {
fmt.Fprintf(o, "Output of one verb may be chained as input to another using \"then\", e.g.\n")
fmt.Fprintf(o, " %s stats1 -a min,mean,max -f flag,u,v -g color then sort -f color\n", argv0)
}
//func mainUsageAuxents(o *os.File, argv0 string) {
// fmt.Fprintf(o, "Miller has a few otherwise-standalone executables packaged within it.\n");
// fmt.Fprintf(o, "They do not participate in any other parts of Miller.\n");
// show_aux_entries(o);
//}
func mainUsageSeeAlso(o *os.File, argv0 string) {
fmt.Fprintf(o, "For more information please see http://johnkerl.org/miller/doc and/or\n")
fmt.Fprintf(o, "http://github.com/johnkerl/miller.")
fmt.Fprintf(o, " This is Miller version %s.\n", version.STRING)
}
func usageUnrecognizedVerb(argv0 string, arg string) {
fmt.Fprintf(os.Stderr, "%s: option \"%s\" not recognized.\n", argv0, arg)
fmt.Fprintf(os.Stderr, "Please run \"%s --help\" for usage information.\n", argv0)
os.Exit(1)
}