diff --git a/src/cut/cut.rs b/src/cut/cut.rs index 516990b7c..c8540a35a 100644 --- a/src/cut/cut.rs +++ b/src/cut/cut.rs @@ -405,16 +405,16 @@ fn cut_files(mut filenames: Vec, mode: Mode) -> i32 { pub fn uumain(args: Vec) -> i32 { let mut opts = getopts::Options::new(); - opts.optopt("b", "bytes", "select only these bytes", "LIST"); - opts.optopt("c", "characters", "select only these characters", "LIST"); - opts.optopt("d", "delimiter", "use DELIM instead of TAB for field delimiter", "DELIM"); - opts.optopt("f", "fields", "select only these fields; also print any line that contains no delimiter character, unless the -s option is specified", "LIST"); - opts.optflag("n", "", "(ignored)"); - opts.optflag("", "complement", "complement the set of selected bytes, characters or fields"); - opts.optflag("s", "only-delimited", "do not print lines not containing delimiters"); - opts.optopt("", "output-delimiter", "use STRING as the output delimiter the default is to use the input delimiter", "STRING"); - opts.optflag("", "help", "display this help and exit"); - opts.optflag("", "version", "output version information and exit"); + opts.optopt("b", "bytes", "filter byte columns from the input source", "sequence"); + opts.optopt("c", "characters", "alias for character mode", "sequence"); + opts.optopt("d", "delimiter", "specify the delimiter character that separates fields in the input source. Defaults to Tab.", "delimiter"); + opts.optopt("f", "fields", "filter field columns from the input source", "sequence"); + opts.optflag("n", "", "legacy option - has no effect."); + opts.optflag("", "complement", "invert the filter - instead of displaying only the filtered columns, display all but those columns"); + opts.optflag("s", "only-delimited", "in field mode, only print lines which contain the delimiter"); + opts.optopt("", "output-delimiter", "in field mode, replace the delimiter in output lines with this option's argument", "new delimiter"); + opts.optflag("", "help", "print usage information"); + opts.optflag("", "version", "print version information"); let matches = match opts.parse(&args[1..]) { Ok(m) => m, @@ -425,24 +425,83 @@ pub fn uumain(args: Vec) -> i32 { }; if matches.opt_present("help") { - println!("{} {}", NAME, VERSION); - println!(""); - println!("Usage:"); - println!(" {0} OPTION... [FILE]...", NAME); - println!(""); - println!("{}", opts.usage("Print selected parts of lines from each FILE to standard output.")); - println!(""); - println!("Use one, and only one of -b, -c or -f. Each LIST is made up of one"); - println!("range, or many ranges separated by commas. Selected input is written"); - println!("in the same order that it is read, and is written exactly once."); - println!("Each range is one of:"); - println!(""); - println!(" N N'th byte, character or field, counted from 1"); - println!(" N- from N'th byte, character or field, to end of line"); - println!(" N-M from N'th to M'th (included) byte, character or field"); - println!(" -M from first to M'th (included) byte, character or field"); - println!(""); - println!("With no FILE, or when FILE is -, read standard input."); + print!(" + {0} {1} + + {0} [-d] [-s] [-z] [--output-delimiter] ((-f|-b|-c) {{sequence}}) {{sourcefile}}+ + + {2} + + Reference + + Each call must specify a mode (what to use for columns), + a sequence (which columns to print), and provide a data source + + Specifying a mode + + Use --bytes (-b) or --characters (-c) to specify byte mode + + Use --fields (-f) to specify field mode, where each line is broken into + fields identified by a delimiter character. For example for a typical CSV + you could use this in combination with setting comma as the delimiter + + Specifying a sequence + + A sequence is a group of 1 or more numbers or inclusive ranges separated + by a commas. + + cut -f 2,5-7 some_file.txt + will display the 2nd, 5th, 6th, and 7th field for each source line + + Ranges can extend to the end of the row by excluding the the second number + + cut -f 3- some_file.txt + will display the 3rd field and all fields after for each source line + + The first number of a range can be excluded, and this is effectively the + same as using 1 as the first number: it causes the range to begin at the + first column. Ranges can also display a single column + + cut -f 1,3-5 some_file.txt + will display the 1st, 3rd, 4th, and 5th field for each source line + + The --complement option, when used, inverts the effect of the sequence + + cut --complement -f 4-6 some_file.txt + will display the every field but the 4th, 5th, and 6th + + Specifying a data source + + If no sourcefile arguments are specified, stdin is used as the source of + lines to print + + If sourcefile arguments are specified, stdin is ignored and all files are + read in consecutively if a sourcefile is not successfully read, a warning + will print to stderr, and the eventual status code will be 1, but cut + will continue to read through proceeding sourcefiles + + To print columns from both STDIN and a file argument, use - (dash) as a + sourcefile argument to represent stdin. + + Field Mode options + + The fields in each line are identified by a delimiter (separator) + + Set the delimiter + Set the delimiter which separates fields in the file using the + --delimiter (-d) option. Setting the delimiter is optional. + If not set, a default delimiter of Tab will be used. + + Optionally Filter based on delimiter + If the --only-delimited (-s) flag is provided, only lines which + contain the delimiter will be printed + + Replace the delimiter + If the --output-delimiter option is provided, the argument used for + it will replace the delimiter character in each line printed. This is + useful for transforming tabular data - e.g. to convert a CSV to a + TSV (tab-separated file) +", NAME, VERSION, opts.usage("Prints specified byte or field columns from each line of stdin or the input files")); return 0; }