Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions src/uu/cut/src/cut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,34 @@ fn cut_fields_newline_char_delim<R: Read, W: Write>(
reader: R,
out: &mut W,
ranges: &[Range],
only_delimited: bool,
newline_char: u8,
out_delim: &[u8],
) -> UResult<()> {
let buf_in = BufReader::new(reader);
let mut buf_in = BufReader::new(reader);
let mut segments: Vec<Vec<u8>> = Vec::new();
let mut found_delimiter = false;

// Read segments using read_until, which includes the delimiter in the buffer
// This lets us detect whether a delimiter was actually found
loop {
let mut segment = Vec::new();
if buf_in.read_until(newline_char, &mut segment)? == 0 {
break;
}
// If segment ends with delimiter, we found one - remove it from segment
if segment.last() == Some(&newline_char) {
found_delimiter = true;
segment.pop();
}
segments.push(segment);
}

// With -s (only_delimited), suppress output if no delimiter found
if only_delimited && !found_delimiter {
return Ok(());
}

let segments: Vec<_> = buf_in.split(newline_char).filter_map(|x| x.ok()).collect();
let mut print_delim = false;

for &Range { low, high } in ranges {
Expand Down Expand Up @@ -303,7 +325,14 @@ fn cut_fields<R: Read, W: Write>(
match field_opts.delimiter {
Delimiter::Slice(delim) if delim == [newline_char] => {
let out_delim = opts.out_delimiter.unwrap_or(delim);
cut_fields_newline_char_delim(reader, out, ranges, newline_char, out_delim)
cut_fields_newline_char_delim(
reader,
out,
ranges,
field_opts.only_delimited,
newline_char,
out_delim,
)
}
Delimiter::Slice(delim) => {
let matcher = ExactMatcher::new(delim);
Expand Down
19 changes: 19 additions & 0 deletions tests/by-util/test_cut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,25 @@ fn test_newline_as_delimiter_with_output_delimiter() {
.stdout_only_bytes("a:b\n");
}

#[test]
fn test_newline_as_delimiter_with_only_delimited() {
// When input has no newline delimiter and -s is specified,
// the line should be suppressed (no output)
new_ucmd!()
.args(&["-f1", "-d", "\n", "-s"])
.pipe_in("abc")
.succeeds()
.stdout_only_bytes("");

// When input has newline delimiter and -s is specified,
// it should output the selected field
new_ucmd!()
.args(&["-f1", "-d", "\n", "-s"])
.pipe_in("line1\nline2")
.succeeds()
.stdout_only_bytes("line1\n");
}

#[test]
fn test_multiple_delimiters() {
new_ucmd!()
Expand Down
Loading