Jika Anda tidak keberatan menata ulang baris dan Anda memiliki GNU coreutils (yaitu pada Linux yang tidak tertanam atau Cygwin, tidak terlalu kuno sejak shufmuncul di versi 6.0), shuf("acak") mengatur ulang baris file secara acak. Jadi Anda dapat mengacak file dan mengirim baris m pertama ke dalam satu file dan sisanya ke yang lain.
Tidak ada cara ideal untuk melakukan pengiriman itu. Anda tidak bisa hanya rantai headdan tailkarena headakan buffer di depan. Anda dapat menggunakan split, tetapi Anda tidak mendapatkan fleksibilitas sehubungan dengan nama file output. Anda bisa menggunakan awk, tentu saja:
<input shuf | awk -v m=$m '{ if (NR <= m) {print >"output1"} else {print} }'
Anda dapat menggunakan sed, yang tidak jelas tetapi mungkin lebih cepat untuk file besar.
<input shuf | sed -e "1,${m} w output1" -e "1,${m} d" >output2
Atau Anda dapat menggunakan teeuntuk menggandakan data, jika platform Anda memiliki /dev/fd; tidak apa-apa jika m kecil:
<input shuf | { tee /dev/fd/3 | head -n $m >output1; } 3>&1 | tail -n +$(($m+1)) >output2
Dengan mudah, Anda dapat menggunakan awk untuk mengirimkan setiap baris secara bergantian. Perhatikan bahwa awk tidak pandai menginisialisasi generator angka acaknya; keacakan tidak hanya pasti tidak cocok untuk kriptografi, tetapi bahkan tidak terlalu baik untuk simulasi numerik. Benih akan sama untuk semua doa awk pada sistem apa pun dengan periode satu detik.
<input awk -v N=$(wc -l <input) -v m=3 '
BEGIN {srand()}
{
if (rand() * N < m) {--m; print >"output1"} else {print >"output2"}
--N;
}'
Jika Anda membutuhkan keacakan yang lebih baik, Anda dapat melakukan hal yang sama di Perl, yang menanamkan RNG dengan baik.
<input perl -e '
open OUT1, ">", "output1" or die $!;
open OUT2, ">", "output2" or die $!;
my $N = `wc -l <input`;
my $m = $ARGV[0];
while (<STDIN>) {
if (rand($N) < $m) { --$m; print OUT1 $_; } else { print OUT2 $_; }
--$N;
}
close OUT1 or die $!;
close OUT2 or die $!;
' 42