Supondo que você tenha memória suficiente para fazer slurp no arquivo, tente
perl -e 'use List::Util 'shuffle'; @k=shuffle(<>); print @k[0..999]' file.bed
Como você deseja fazer isso 10000 vezes, recomendo integrar a repetição no script e embaralhar os índices da própria matriz para acelerar as coisas:
$ time perl -e 'use List::Util 'shuffle';
@l=<>; for $i (1..10000){
open(my $fh, ">","file.$i.bed");
@r=shuffle(0..$#l);
print $fh @l[@r[0..999]]
}' file.bed
real 1m12.444s
user 1m8.536s
sys 0m3.244s
O arquivo acima criou 10000 arquivos de 1000 linhas cada, de um arquivo que continha 37000 linhas (seu arquivo de exemplo foi repetido 1000 vezes). Como você pode ver, levou mais de três minutos no meu sistema.
Explicação
-
use List::Util 'shuffle';
: isso importa um módulo Perl que fornece a funçãoshuffle()
que randomiza uma matriz. -
@l=<>;
: carrega o arquivo de entrada (<>
) na matriz@l
. -
for $i (1..10000){}
: execute isso 10000 vezes. -
@r=shuffle(0..$#l);
:$#l
é o número de elementos em@l
então@r
agora é uma lista aleatória dos números de índice da matriz@l
(as linhas do arquivo de entrada). -
open(my $fh, ">","file.$i.bed");
: abra um arquivo chamadofile.$i.bed
para gravação.$i
terá valores de 1 a 10000. -
print $fh @l[@r[0..999]]
: pegue os primeiros 1000 índices na matriz embaralhada e imprima as linhas correspondentes (elementos de@l
).
Outra abordagem é usar shuf
( obrigado @frostschutz ):
$ time for i in {1..10000}; do shuf -n 1000 file.bed > file.$i.abed; done
real 1m9.743s
user 0m23.732s
sys 0m31.764s