diff --git a/src/sed/processor.rs b/src/sed/processor.rs index a2d33e0..070c815 100644 --- a/src/sed/processor.rs +++ b/src/sed/processor.rs @@ -631,8 +631,12 @@ fn process_file( 'x' => { // Exchange the contents of the pattern and hold spaces. let (pat_content, pat_has_newline) = pattern.fields_mut()?; + + // Swap newline if hold space is logically non-empty. + if !context.hold.content.is_empty() || context.hold.has_newline { + std::mem::swap(pat_has_newline, &mut context.hold.has_newline); + } std::mem::swap(pat_content, &mut context.hold.content); - std::mem::swap(pat_has_newline, &mut context.hold.has_newline); } 'y' => { let trans = extract_variant!(command, Transliteration); diff --git a/tests/by-util/test_sed.rs b/tests/by-util/test_sed.rs index 9091dc9..0d43957 100644 --- a/tests/by-util/test_sed.rs +++ b/tests/by-util/test_sed.rs @@ -1195,3 +1195,14 @@ fn test_print_command_adds_newline() { .succeeds() .stdout_is("foo\nfoo"); } + +//////////////////////////////////////////////////////////// +// Test for issue #254: Missing newline in exchanged output with `2x` +#[test] +fn test_exchange_command_adds_newline() { + new_ucmd!() + .args(&["2x"]) + .pipe_in("a\nb\nc\n") + .succeeds() + .stdout_is("a\n\nc\n"); +}