From f2ac3ee88f40e310ad5b360a7e7cb716045d6f1a Mon Sep 17 00:00:00 2001 From: Anthony DePasquale Date: Sun, 4 Oct 2026 11:29:54 +0200 Subject: [PATCH] sed: discard text queued by a, r and R on Q, as GNU sed does --- src/sed/processor.rs | 2 ++ tests/by-util/test_sed.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/sed/processor.rs b/src/sed/processor.rs index 298a974e..3b9cf5b3 100644 --- a/src/sed/processor.rs +++ b/src/sed/processor.rs @@ -830,6 +830,8 @@ fn process_file( ); context.stop_processing = true; context.quiet = true; + // Like GNU sed, discard text queued by `a`, `r` and `R`. + context.append_elements.clear(); break; } 'R' => { diff --git a/tests/by-util/test_sed.rs b/tests/by-util/test_sed.rs index 5597d2fe..573495ab 100644 --- a/tests/by-util/test_sed.rs +++ b/tests/by-util/test_sed.rs @@ -3065,6 +3065,38 @@ fn test_quit_no_newline() { .stdout_is("foo\n"); } +/// `Q` discards text queued by `a`, `r` and `R`, as GNU sed does. +#[test] +fn test_quit_silently_discards_appended_text() -> std::io::Result<()> { + new_ucmd!() + .args(&["-e", "a A", "-e", "Q"]) + .pipe_in("x\n") + .succeeds() + .stdout_is(""); + + let dir = tempfile::tempdir()?; + let (one, two, text) = ( + dir.path().join("1"), + dir.path().join("2"), + dir.path().join("text"), + ); + fs::write(&one, "a")?; + fs::write(&two, "b\n")?; + fs::write(&text, "X\n")?; + new_ucmd!() + .args(&["-e", &format!("R {}", text.display()), "-e", "Q"]) + .pipe_in("x\n") + .succeeds() + .stdout_is(""); + new_ucmd!() + .args(&["-e", &format!("2r {}", text.display()), "-e", "2Q"]) + .arg(&one) + .arg(&two) + .succeeds() + .stdout_is("a"); + Ok(()) +} + // P with single line no newline input #[test] fn test_print_first_line_no_newline() {