mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Merge pull request #946 from ChrisNikkel/feature/zero_terminated
uniq: add -z option to allow for zero terminated input and output
This commit is contained in:
commit
1880c46acd
4 changed files with 26 additions and 4 deletions
|
@ -34,6 +34,7 @@ struct Uniq {
|
|||
slice_start: Option<usize>,
|
||||
slice_stop: Option<usize>,
|
||||
ignore_case: bool,
|
||||
zero_terminated: bool,
|
||||
}
|
||||
|
||||
impl Uniq {
|
||||
|
@ -41,9 +42,10 @@ impl Uniq {
|
|||
let mut lines: Vec<String> = vec!();
|
||||
let mut first_line_printed = false;
|
||||
let delimiters = &self.delimiters[..];
|
||||
let line_terminator = self.get_line_terminator();
|
||||
|
||||
for io_line in reader.lines() {
|
||||
let line = crash_if_err!(1, io_line);
|
||||
for io_line in reader.split(line_terminator) {
|
||||
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) {
|
||||
let print_delimiter = delimiters == "prepend" || (delimiters == "separate" && first_line_printed);
|
||||
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 {
|
||||
let fields_to_check = &self.skip_fields(line);
|
||||
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) {
|
||||
let line_terminator = self.get_line_terminator();
|
||||
|
||||
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 {
|
||||
|
@ -125,7 +137,7 @@ impl Uniq {
|
|||
} else {
|
||||
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.optflag("i", "ignore-case", "ignore differences in case when comparing");
|
||||
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("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_stop: opt_parsed("check-chars", &matches),
|
||||
ignore_case: matches.opt_present("ignore-case"),
|
||||
zero_terminated: matches.opt_present("zero-terminated"),
|
||||
};
|
||||
uniq.print_uniq(&mut open_input_file(in_file_name),
|
||||
&mut open_output_file(out_file_name));
|
||||
|
|
BIN
tests/fixtures/uniq/sorted-zero-terminated.expected
vendored
Normal file
BIN
tests/fixtures/uniq/sorted-zero-terminated.expected
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/uniq/sorted-zero-terminated.txt
vendored
Normal file
BIN
tests/fixtures/uniq/sorted-zero-terminated.txt
vendored
Normal file
Binary file not shown.
|
@ -8,6 +8,7 @@ fn new_ucmd() -> UCommand {
|
|||
static INPUT: &'static str = "sorted.txt";
|
||||
static SKIP_CHARS: &'static str = "skip-chars.txt";
|
||||
static SKIP_FIELDS: &'static str = "skip-fields.txt";
|
||||
static SORTED_ZERO_TERMINATED: &'static str = "sorted-zero-terminated.txt";
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
|
@ -92,3 +93,10 @@ fn test_stdin_repeated_only() {
|
|||
.args(&["-d"]).pipe_in_fixture(INPUT)
|
||||
.run().stdout_is_fixture("sorted-repeated-only.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_zero_terminated() {
|
||||
new_ucmd()
|
||||
.args(&["-z"]).pipe_in_fixture(SORTED_ZERO_TERMINATED)
|
||||
.run().stdout_is_fixture("sorted-zero-terminated.expected");
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue