Skip to content

Commit b9649a6

Browse files
committed
cut: fix -s flag ignored when delimiter is newline
When using newline as the delimiter (-d $'\n') with -s (only-delimited), cut should suppress lines that do not contain the delimiter. However, cut_fields_newline_char_delim() was not checking the only_delimited flag, causing it to always output even when -s was specified. This commit: - Adds only_delimited parameter to cut_fields_newline_char_delim() - Checks if input has no delimiter and only_delimited is true, returns early - Adds test case for newline delimiter with -s flag Fixes #10012
1 parent 81ee8d1 commit b9649a6

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/uu/cut/src/cut.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,20 @@ fn cut_fields_newline_char_delim<R: Read, W: Write>(
265265
reader: R,
266266
out: &mut W,
267267
ranges: &[Range],
268+
only_delimited: bool,
268269
newline_char: u8,
269270
out_delim: &[u8],
270271
) -> UResult<()> {
271272
let buf_in = BufReader::new(reader);
272273

273274
let segments: Vec<_> = buf_in.split(newline_char).filter_map(|x| x.ok()).collect();
275+
276+
// If there's only one segment, it means no delimiter was found in the input.
277+
// With -s (only_delimited), we should suppress lines without delimiters.
278+
if segments.len() <= 1 && only_delimited {
279+
return Ok(());
280+
}
281+
274282
let mut print_delim = false;
275283

276284
for &Range { low, high } in ranges {
@@ -303,7 +311,14 @@ fn cut_fields<R: Read, W: Write>(
303311
match field_opts.delimiter {
304312
Delimiter::Slice(delim) if delim == [newline_char] => {
305313
let out_delim = opts.out_delimiter.unwrap_or(delim);
306-
cut_fields_newline_char_delim(reader, out, ranges, newline_char, out_delim)
314+
cut_fields_newline_char_delim(
315+
reader,
316+
out,
317+
ranges,
318+
field_opts.only_delimited,
319+
newline_char,
320+
out_delim,
321+
)
307322
}
308323
Delimiter::Slice(delim) => {
309324
let matcher = ExactMatcher::new(delim);

tests/by-util/test_cut.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,25 @@ fn test_newline_as_delimiter_with_output_delimiter() {
301301
.stdout_only_bytes("a:b\n");
302302
}
303303

304+
#[test]
305+
fn test_newline_as_delimiter_with_only_delimited() {
306+
// When input has no newline delimiter and -s is specified,
307+
// the line should be suppressed (no output)
308+
new_ucmd!()
309+
.args(&["-f1", "-d", "\n", "-s"])
310+
.pipe_in("abc")
311+
.succeeds()
312+
.stdout_only_bytes("");
313+
314+
// When input has newline delimiter and -s is specified,
315+
// it should output the selected field
316+
new_ucmd!()
317+
.args(&["-f1", "-d", "\n", "-s"])
318+
.pipe_in("line1\nline2")
319+
.succeeds()
320+
.stdout_only_bytes("line1\n");
321+
}
322+
304323
#[test]
305324
fn test_multiple_delimiters() {
306325
new_ucmd!()

0 commit comments

Comments
 (0)