mirror of
https://github.com/uutils/coreutils
synced 2024-11-16 01:38:04 +00:00
uniq: add command line option -z for zero terminated input and output
This commit is contained in:
parent
c0b2da7c01
commit
cdfdc3a2bd
1 changed files with 18 additions and 4 deletions
|
@ -34,6 +34,7 @@ struct Uniq {
|
||||||
slice_start: Option<usize>,
|
slice_start: Option<usize>,
|
||||||
slice_stop: Option<usize>,
|
slice_stop: Option<usize>,
|
||||||
ignore_case: bool,
|
ignore_case: bool,
|
||||||
|
zero_terminated: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Uniq {
|
impl Uniq {
|
||||||
|
@ -41,9 +42,10 @@ impl Uniq {
|
||||||
let mut lines: Vec<String> = vec!();
|
let mut lines: Vec<String> = vec!();
|
||||||
let mut first_line_printed = false;
|
let mut first_line_printed = false;
|
||||||
let delimiters = &self.delimiters[..];
|
let delimiters = &self.delimiters[..];
|
||||||
|
let line_terminator = self.get_line_terminator();
|
||||||
|
|
||||||
for io_line in reader.lines() {
|
for io_line in reader.split(line_terminator) {
|
||||||
let line = crash_if_err!(1, io_line);
|
let line = String::from_utf8(crash_if_err!(1, io_line)).unwrap();
|
||||||
if !lines.is_empty() && self.cmp_key(&lines[0]) != self.cmp_key(&line) {
|
if !lines.is_empty() && self.cmp_key(&lines[0]) != self.cmp_key(&line) {
|
||||||
let print_delimiter = delimiters == "prepend" || (delimiters == "separate" && first_line_printed);
|
let print_delimiter = delimiters == "prepend" || (delimiters == "separate" && first_line_printed);
|
||||||
first_line_printed |= self.print_lines(writer, &lines, print_delimiter);
|
first_line_printed |= self.print_lines(writer, &lines, print_delimiter);
|
||||||
|
@ -80,6 +82,14 @@ impl Uniq {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_line_terminator(&self) -> u8 {
|
||||||
|
if self.zero_terminated {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
'\n' as u8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn cmp_key(&self, line: &str) -> String {
|
fn cmp_key(&self, line: &str) -> String {
|
||||||
let fields_to_check = &self.skip_fields(line);
|
let fields_to_check = &self.skip_fields(line);
|
||||||
let len = fields_to_check.len();
|
let len = fields_to_check.len();
|
||||||
|
@ -116,8 +126,10 @@ impl Uniq {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_line<W: Write>(&self, writer: &mut BufWriter<W>, line: &str, count: usize, print_delimiter: bool) {
|
fn print_line<W: Write>(&self, writer: &mut BufWriter<W>, line: &str, count: usize, print_delimiter: bool) {
|
||||||
|
let line_terminator = self.get_line_terminator();
|
||||||
|
|
||||||
if print_delimiter {
|
if print_delimiter {
|
||||||
crash_if_err!(1, writer.write_all(&['\n' as u8]));
|
crash_if_err!(1, writer.write_all(&[line_terminator]));
|
||||||
}
|
}
|
||||||
|
|
||||||
crash_if_err!(1, if self.show_counts {
|
crash_if_err!(1, if self.show_counts {
|
||||||
|
@ -125,7 +137,7 @@ impl Uniq {
|
||||||
} else {
|
} else {
|
||||||
writer.write_all(line.as_bytes())
|
writer.write_all(line.as_bytes())
|
||||||
});
|
});
|
||||||
crash_if_err!(1, writer.write_all("\n".as_bytes()));
|
crash_if_err!(1, writer.write_all(&[line_terminator]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +165,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
opts.optopt("w", "check-chars", "compare no more than N characters in lines", "N");
|
opts.optopt("w", "check-chars", "compare no more than N characters in lines", "N");
|
||||||
opts.optflag("i", "ignore-case", "ignore differences in case when comparing");
|
opts.optflag("i", "ignore-case", "ignore differences in case when comparing");
|
||||||
opts.optflag("u", "unique", "only print unique lines");
|
opts.optflag("u", "unique", "only print unique lines");
|
||||||
|
opts.optflag("z", "zero-terminated", "end lines with 0 byte, not newline");
|
||||||
opts.optflag("h", "help", "display this help and exit");
|
opts.optflag("h", "help", "display this help and exit");
|
||||||
opts.optflag("V", "version", "output version information and exit");
|
opts.optflag("V", "version", "output version information and exit");
|
||||||
|
|
||||||
|
@ -202,6 +215,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
slice_start: opt_parsed("skip-chars", &matches),
|
slice_start: opt_parsed("skip-chars", &matches),
|
||||||
slice_stop: opt_parsed("check-chars", &matches),
|
slice_stop: opt_parsed("check-chars", &matches),
|
||||||
ignore_case: matches.opt_present("ignore-case"),
|
ignore_case: matches.opt_present("ignore-case"),
|
||||||
|
zero_terminated: matches.opt_present("zero-terminated"),
|
||||||
};
|
};
|
||||||
uniq.print_uniq(&mut open_input_file(in_file_name),
|
uniq.print_uniq(&mut open_input_file(in_file_name),
|
||||||
&mut open_output_file(out_file_name));
|
&mut open_output_file(out_file_name));
|
||||||
|
|
Loading…
Reference in a new issue