mirror of
https://github.com/johnkerl/miller.git
synced 2026-01-23 02:14:13 +00:00
526 lines
28 KiB
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)
|
|
}
|