Skip to content

Commit 7e05833

Browse files
authored
Merge pull request #3205 from jfinkels/split-round-robin
split: implement round-robin arg to --number
2 parents 161db4c + 18bfd1a commit 7e05833

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/uu/split/src/split.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,46 @@ where
11621162
Ok(())
11631163
}
11641164

1165+
fn split_into_n_chunks_by_line_round_robin<R>(
1166+
settings: &Settings,
1167+
reader: &mut R,
1168+
num_chunks: u64,
1169+
) -> UResult<()>
1170+
where
1171+
R: BufRead,
1172+
{
1173+
// This object is responsible for creating the filename for each chunk.
1174+
let mut filename_iterator = FilenameIterator::new(
1175+
&settings.prefix,
1176+
&settings.additional_suffix,
1177+
settings.suffix_length,
1178+
settings.suffix_type,
1179+
);
1180+
1181+
// Create one writer for each chunk. This will create each
1182+
// of the underlying files (if not in `--filter` mode).
1183+
let mut writers = vec![];
1184+
for _ in 0..num_chunks {
1185+
let filename = filename_iterator
1186+
.next()
1187+
.ok_or_else(|| USimpleError::new(1, "output file suffixes exhausted"))?;
1188+
let writer = platform::instantiate_current_writer(&settings.filter, filename.as_str());
1189+
writers.push(writer);
1190+
}
1191+
1192+
let num_chunks: usize = num_chunks.try_into().unwrap();
1193+
for (i, line_result) in reader.lines().enumerate() {
1194+
let line = line_result.unwrap();
1195+
let maybe_writer = writers.get_mut(i % num_chunks);
1196+
let writer = maybe_writer.unwrap();
1197+
let bytes = line.as_bytes();
1198+
writer.write_all(bytes)?;
1199+
writer.write_all(b"\n")?;
1200+
}
1201+
1202+
Ok(())
1203+
}
1204+
11651205
fn split(settings: &Settings) -> UResult<()> {
11661206
let mut reader = BufReader::new(if settings.input == "-" {
11671207
Box::new(stdin()) as Box<dyn Read>
@@ -1188,6 +1228,9 @@ fn split(settings: &Settings) -> UResult<()> {
11881228
let chunk_number = chunk_number - 1;
11891229
kth_chunk_by_line(settings, &mut reader, chunk_number, num_chunks)
11901230
}
1231+
Strategy::Number(NumberType::RoundRobin(num_chunks)) => {
1232+
split_into_n_chunks_by_line_round_robin(settings, &mut reader, num_chunks)
1233+
}
11911234
Strategy::Number(_) => Err(USimpleError::new(1, "-n mode not yet fully implemented")),
11921235
Strategy::Lines(chunk_size) => {
11931236
let mut writer = LineChunkWriter::new(chunk_size, settings)

tests/by-util/test_split.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,3 +605,19 @@ fn test_line_bytes() {
605605
assert_eq!(at.read("xac"), "cccc\ndd\n");
606606
assert_eq!(at.read("xad"), "ee\n");
607607
}
608+
609+
#[test]
610+
fn test_round_robin() {
611+
let (at, mut ucmd) = at_and_ucmd!();
612+
613+
let file_read = |f| {
614+
let mut s = String::new();
615+
at.open(f).read_to_string(&mut s).unwrap();
616+
s
617+
};
618+
619+
ucmd.args(&["-n", "r/2", "fivelines.txt"]).succeeds();
620+
621+
assert_eq!(file_read("xaa"), "1\n3\n5\n");
622+
assert_eq!(file_read("xab"), "2\n4\n");
623+
}

0 commit comments

Comments
 (0)