Das ist vielleicht nicht der effizienteste Weg, aber es funktioniert:
shuf <file> > tmp
head -n $m tmp > out1
tail -n +$(( m + 1 )) tmp > out2
Mit $m
enthält die Anzahl der Zeilen.
Dieses bash/awk-Skript wählt zufällig Zeilen aus und behält die ursprüngliche Reihenfolge in beiden Ausgabedateien bei.
awk -v m=4 -v N=$(wc -l <file) -v out1=/tmp/out1 -v out2=/tmp/out2 \
'BEGIN{ srand()
do{ lnb = 1 + int(rand()*N)
if ( !(lnb in R) ) {
R[lnb] = 1
ct++ }
} while (ct<m)
} { if (R[NR]==1) print > out1
else print > out2
}' file
cat /tmp/out1
echo ========
cat /tmp/out2
Ausgabe, basierend auf den Daten in der Frage.
12345
23456
200
600
========
67891
-20000
20
Wie bei allen Unix-Dingen gibt es dafür ein Dienstprogramm.
Tagesprogramm:split
split
teilt eine Datei auf viele verschiedene Arten, -b
Bytes, -l
Zeilen, -n
Anzahl der Ausgabedateien. Wir werden den -l
verwenden Möglichkeit. Da Sie zufällige Zeilen auswählen möchten und nicht nur die erste m
, werden wir sort
die Datei zufällig zuerst. Wenn Sie über sort
lesen möchten , siehe meine Antwort hier.
Nun der eigentliche Code. Es ist wirklich ganz einfach:
sort -R input_file | split -l $m output_prefix
Dadurch werden zwei Dateien erstellt, eine mit m
Zeilen und eine mit N-m
Zeilen mit dem Namen output_prefixaa
und output_prefixab
.Stellen Sie sicher, dass m
ist die gewünschte größere Datei oder Sie erhalten mehrere Dateien der Länge m
(und eine mit N % m
).
Wenn Sie sicherstellen möchten, dass Sie die richtige Größe verwenden, finden Sie hier einen kleinen Code dafür:
m=10 # size you want one file to be
N=$(wc -l input_file)
m=$(( m > N/2 ? m : N - m ))
sort -R input_file | split -l $m output_prefix
Bearbeiten:Mir ist aufgefallen, dass einige sort
Implementierungen haben keinen -R
Flagge. Wenn Sie perl
haben , können Sie perl -e 'use List::Util qw/shuffle/; print shuffle <>;'
ersetzen .