diff --git a/src/lib.rs b/src/lib.rs index df2b56a..0f2b63a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -707,14 +707,16 @@ pub fn uu_app() -> Command { .short('L') .long("files-without-match") .help("print only names of FILEs with no selected lines") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .overrides_with("files_with_matches"), ) .arg( Arg::new("files_with_matches") .short('l') .long("files-with-matches") .help("print only names of FILEs with selected lines") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .overrides_with("files_without_match"), ) .arg( Arg::new("count") diff --git a/tests/test_grep.rs b/tests/test_grep.rs index 5e487ea..d061918 100644 --- a/tests/test_grep.rs +++ b/tests/test_grep.rs @@ -460,6 +460,25 @@ fn files_with_and_without_matches() { .stdout_only("many\n"); } +#[test] +fn files_with_and_without_matches_mutually_exclusive() { + // Test that -l and -L are mutually exclusive with last-one-wins semantics + let (scene, mut c) = ucmd(); + scene.fixtures.write("file", "match\n"); + + // -l -L: last flag (-L) wins, so no output (file has match, -L excludes it) + c.args(&["-l", "-L", "match", "file"]) + .succeeds() + .stdout_only(""); + + // -L -l: last flag (-l) wins, so filename is printed + let (scene, mut c) = ucmd(); + scene.fixtures.write("file", "match\n"); + c.args(&["-L", "-l", "match", "file"]) + .succeeds() + .stdout_only("file\n"); +} + #[test] fn count_combined_with_listing_flags() { let (scene, _) = ucmd();