Questo potrebbe non essere il modo più efficiente ma funziona:
shuf <file> > tmp
head -n $m tmp > out1
tail -n +$(( m + 1 )) tmp > out2
Con $m
contenente il numero di righe.
Questo script bash/awk sceglie le righe a caso e mantiene la sequenza originale in entrambi i file di output.
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
Output, basato sui dati nella domanda.
12345
23456
200
600
========
67891
-20000
20
Come per tutte le cose Unix, c'è un'utility per questo.
Programma della giornata:split
split
dividerà un file in molti modi diversi, -b
byte, -l
righe, -n
numero di file di output. Useremo il -l
opzione. Dal momento che vuoi scegliere righe casuali e non solo le prime m
, faremo sort
il file in modo casuale prima. Se vuoi leggere di sort
, fai riferimento alla mia risposta qui.
Ora, il codice vero e proprio. È abbastanza semplice, davvero:
sort -R input_file | split -l $m output_prefix
Questo creerà due file, uno con m
righe e una con N-m
righe, denominate output_prefixaa
e output_prefixab
.Assicurati che m
è il file più grande che desideri o otterrai diversi file di lunghezza m
(e uno con N % m
).
Se vuoi assicurarti di utilizzare la dimensione corretta, ecco un piccolo codice per farlo:
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
Modifica:è venuto alla mia attenzione che alcuni sort
le implementazioni non hanno un -R
bandiera. Se hai perl
, puoi sostituire perl -e 'use List::Util qw/shuffle/; print shuffle <>;'
.