mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Merge pull request #3205 from jfinkels/split-round-robin
split: implement round-robin arg to --number
This commit is contained in:
commit
7e05833b96
2 changed files with 59 additions and 0 deletions
|
@ -1162,6 +1162,46 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn split_into_n_chunks_by_line_round_robin<R>(
|
||||||
|
settings: &Settings,
|
||||||
|
reader: &mut R,
|
||||||
|
num_chunks: u64,
|
||||||
|
) -> UResult<()>
|
||||||
|
where
|
||||||
|
R: BufRead,
|
||||||
|
{
|
||||||
|
// This object is responsible for creating the filename for each chunk.
|
||||||
|
let mut filename_iterator = FilenameIterator::new(
|
||||||
|
&settings.prefix,
|
||||||
|
&settings.additional_suffix,
|
||||||
|
settings.suffix_length,
|
||||||
|
settings.suffix_type,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create one writer for each chunk. This will create each
|
||||||
|
// of the underlying files (if not in `--filter` mode).
|
||||||
|
let mut writers = vec![];
|
||||||
|
for _ in 0..num_chunks {
|
||||||
|
let filename = filename_iterator
|
||||||
|
.next()
|
||||||
|
.ok_or_else(|| USimpleError::new(1, "output file suffixes exhausted"))?;
|
||||||
|
let writer = platform::instantiate_current_writer(&settings.filter, filename.as_str());
|
||||||
|
writers.push(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
let num_chunks: usize = num_chunks.try_into().unwrap();
|
||||||
|
for (i, line_result) in reader.lines().enumerate() {
|
||||||
|
let line = line_result.unwrap();
|
||||||
|
let maybe_writer = writers.get_mut(i % num_chunks);
|
||||||
|
let writer = maybe_writer.unwrap();
|
||||||
|
let bytes = line.as_bytes();
|
||||||
|
writer.write_all(bytes)?;
|
||||||
|
writer.write_all(b"\n")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn split(settings: &Settings) -> UResult<()> {
|
fn split(settings: &Settings) -> UResult<()> {
|
||||||
let mut reader = BufReader::new(if settings.input == "-" {
|
let mut reader = BufReader::new(if settings.input == "-" {
|
||||||
Box::new(stdin()) as Box<dyn Read>
|
Box::new(stdin()) as Box<dyn Read>
|
||||||
|
@ -1188,6 +1228,9 @@ fn split(settings: &Settings) -> UResult<()> {
|
||||||
let chunk_number = chunk_number - 1;
|
let chunk_number = chunk_number - 1;
|
||||||
kth_chunk_by_line(settings, &mut reader, chunk_number, num_chunks)
|
kth_chunk_by_line(settings, &mut reader, chunk_number, num_chunks)
|
||||||
}
|
}
|
||||||
|
Strategy::Number(NumberType::RoundRobin(num_chunks)) => {
|
||||||
|
split_into_n_chunks_by_line_round_robin(settings, &mut reader, num_chunks)
|
||||||
|
}
|
||||||
Strategy::Number(_) => Err(USimpleError::new(1, "-n mode not yet fully implemented")),
|
Strategy::Number(_) => Err(USimpleError::new(1, "-n mode not yet fully implemented")),
|
||||||
Strategy::Lines(chunk_size) => {
|
Strategy::Lines(chunk_size) => {
|
||||||
let mut writer = LineChunkWriter::new(chunk_size, settings)
|
let mut writer = LineChunkWriter::new(chunk_size, settings)
|
||||||
|
|
|
@ -605,3 +605,19 @@ fn test_line_bytes() {
|
||||||
assert_eq!(at.read("xac"), "cccc\ndd\n");
|
assert_eq!(at.read("xac"), "cccc\ndd\n");
|
||||||
assert_eq!(at.read("xad"), "ee\n");
|
assert_eq!(at.read("xad"), "ee\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_round_robin() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
|
||||||
|
let file_read = |f| {
|
||||||
|
let mut s = String::new();
|
||||||
|
at.open(f).read_to_string(&mut s).unwrap();
|
||||||
|
s
|
||||||
|
};
|
||||||
|
|
||||||
|
ucmd.args(&["-n", "r/2", "fivelines.txt"]).succeeds();
|
||||||
|
|
||||||
|
assert_eq!(file_read("xaa"), "1\n3\n5\n");
|
||||||
|
assert_eq!(file_read("xab"), "2\n4\n");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue