diff --git a/src/uu/comm/src/comm.rs b/src/uu/comm/src/comm.rs index a3b4bbde2..b91f9ddbc 100644 --- a/src/uu/comm/src/comm.rs +++ b/src/uu/comm/src/comm.rs @@ -29,6 +29,7 @@ mod options { pub const DELIMITER_DEFAULT: &str = "\t"; pub const FILE_1: &str = "FILE1"; pub const FILE_2: &str = "FILE2"; + pub const TOTAL: &str = "total"; } fn mkdelim(col: usize, opts: &ArgMatches) -> String { @@ -76,6 +77,10 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &ArgMatches) { let rb = &mut String::new(); let mut nb = b.read_line(rb); + let mut total_col_1 = 0; + let mut total_col_2 = 0; + let mut total_col_3 = 0; + while na.is_ok() || nb.is_ok() { let ord = match (na.is_ok(), nb.is_ok()) { (false, true) => Ordering::Greater, @@ -97,6 +102,7 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &ArgMatches) { } ra.clear(); na = a.read_line(ra); + total_col_1 += 1; } Ordering::Greater => { if !opts.get_flag(options::COLUMN_2) { @@ -105,6 +111,7 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &ArgMatches) { } rb.clear(); nb = b.read_line(rb); + total_col_2 += 1; } Ordering::Equal => { if !opts.get_flag(options::COLUMN_3) { @@ -115,9 +122,14 @@ fn comm(a: &mut LineReader, b: &mut LineReader, opts: &ArgMatches) { rb.clear(); na = a.read_line(ra); nb = b.read_line(rb); + total_col_3 += 1; } } } + + if opts.get_flag(options::TOTAL) { + println!("{total_col_1}\t{total_col_2}\t{total_col_3}\ttotal"); + } } fn open_file(name: &str) -> io::Result { @@ -187,4 +199,10 @@ pub fn uu_app() -> Command { .required(true) .value_hint(clap::ValueHint::FilePath), ) + .arg( + Arg::new(options::TOTAL) + .long(options::TOTAL) + .help("output a summary") + .action(ArgAction::SetTrue), + ) } diff --git a/tests/by-util/test_comm.rs b/tests/by-util/test_comm.rs index 9fc175c7f..77df66452 100644 --- a/tests/by-util/test_comm.rs +++ b/tests/by-util/test_comm.rs @@ -55,6 +55,22 @@ fn empty_empty() { .stdout_only_fixture("emptyempty.expected"); // spell-checker:disable-line } +#[test] +fn total() { + new_ucmd!() + .args(&["--total", "a", "b"]) + .succeeds() + .stdout_is_fixture("ab_total.expected"); +} + +#[test] +fn total_with_suppressed_regular_output() { + new_ucmd!() + .args(&["--total", "-123", "a", "b"]) + .succeeds() + .stdout_is_fixture("ab_total_suppressed_regular_output.expected"); +} + #[test] fn output_delimiter() { new_ucmd!() diff --git a/tests/fixtures/comm/ab_total.expected b/tests/fixtures/comm/ab_total.expected new file mode 100644 index 000000000..430354a66 --- /dev/null +++ b/tests/fixtures/comm/ab_total.expected @@ -0,0 +1,4 @@ +a + b + z +1 1 1 total diff --git a/tests/fixtures/comm/ab_total_suppressed_regular_output.expected b/tests/fixtures/comm/ab_total_suppressed_regular_output.expected new file mode 100644 index 000000000..733c1d344 --- /dev/null +++ b/tests/fixtures/comm/ab_total_suppressed_regular_output.expected @@ -0,0 +1 @@ +1 1 1 total