@@ -9,7 +9,7 @@ use bstr::io::BufReadExt;
99use clap:: { builder:: ValueParser , crate_version, Arg , ArgAction , ArgMatches , Command } ;
1010use std:: ffi:: OsString ;
1111use std:: fs:: File ;
12- use std:: io:: { stdin, stdout, BufReader , BufWriter , IsTerminal , Read , Write } ;
12+ use std:: io:: { stdin, stdout, BufRead , BufReader , BufWriter , IsTerminal , Read , Write } ;
1313use std:: path:: Path ;
1414use uucore:: display:: Quotable ;
1515use uucore:: error:: { set_exit_code, FromIo , UResult , USimpleError } ;
@@ -267,10 +267,45 @@ fn cut_fields_implicit_out_delim<R: Read, M: Matcher>(
267267 Ok ( ( ) )
268268}
269269
270+ fn cut_fields_newline_char_delim < R : Read > (
271+ reader : R ,
272+ ranges : & [ Range ] ,
273+ newline_char : u8 ,
274+ out_delim : & [ u8 ] ,
275+ ) -> UResult < ( ) > {
276+ let buf_in = BufReader :: new ( reader) ;
277+ let mut out = stdout_writer ( ) ;
278+
279+ let segments: Vec < _ > = buf_in. split ( newline_char) . filter_map ( |x| x. ok ( ) ) . collect ( ) ;
280+ let mut print_delim = false ;
281+
282+ for & Range { low, high } in ranges {
283+ for i in low..=high {
284+ // "- 1" is necessary because fields start from 1 whereas a Vec starts from 0
285+ if let Some ( segment) = segments. get ( i - 1 ) {
286+ if print_delim {
287+ out. write_all ( out_delim) ?;
288+ } else {
289+ print_delim = true ;
290+ }
291+ out. write_all ( segment. as_slice ( ) ) ?;
292+ } else {
293+ break ;
294+ }
295+ }
296+ }
297+ out. write_all ( & [ newline_char] ) ?;
298+ Ok ( ( ) )
299+ }
300+
270301fn cut_fields < R : Read > ( reader : R , ranges : & [ Range ] , opts : & Options ) -> UResult < ( ) > {
271302 let newline_char = opts. line_ending . into ( ) ;
272303 let field_opts = opts. field_opts . as_ref ( ) . unwrap ( ) ; // it is safe to unwrap() here - field_opts will always be Some() for cut_fields() call
273304 match field_opts. delimiter {
305+ Delimiter :: Slice ( delim) if delim == [ newline_char] => {
306+ let out_delim = opts. out_delimiter . unwrap_or ( delim) ;
307+ cut_fields_newline_char_delim ( reader, ranges, newline_char, out_delim)
308+ }
274309 Delimiter :: Slice ( delim) => {
275310 let matcher = ExactMatcher :: new ( delim) ;
276311 match opts. out_delimiter {
0 commit comments