Dans un script Bash, je veux sélectionner N lignes aléatoires du fichier d'entrée et sortir vers un autre fichier.
Comment cela peut-il être fait?
bash
shell
random
text-processing
user121196
la source
la source
sort -R
car cela fait beaucoup de travail excessif, en particulier pour les longs fichiers. Vous pouvez utiliser$RANDOM
,% wc -l
,jot
,sed -n
(à la stackoverflow.com/a/6022431/563329 ), et la fonctionnalité de bash (tableaux, redirection de commande, etc.) pour définir votre proprepeek
fonction qui fait fonctionner sur des fichiers 5.000.000 ligne.Réponses:
Utilisez
shuf
avec l'-n
option comme indiqué ci-dessous, pour obtenirN
des lignes aléatoires:la source
sort -R
?Triez le fichier au hasard et choisissez les premières
100
lignes:la source
sort
trie les lignes identiques ensemble, donc si vous pouvez avoir des lignes en double et que vous avezshuf
(un outil gnu) installé, il est préférable de l'utiliser pour cela.shuf -n
agit assez instantanément.sort -R
est probablement l'option GNU, installez GNU coreutils. btw,shuf
fait également partie de coreutils.sort -R input | head -n <num_lines>
. Le fichier d'entrée était de 279 Go, avec 2 lignes + bi. Je ne peux pas le partager, cependant. Quoi qu'il en soit, le fait est que vous pouvez garder certaines lignes en mémoire avec lecture aléatoire pour faire la sélection aléatoire de ce qui doit être sorti. Trier va trier le fichier entier , quels que soient vos besoins.Eh bien, selon un commentaire sur la réponse shuf, il a mélangé 78 000 000 000 lignes en moins d'une minute.
Défi accepté...
EDIT: j'ai battu mon propre record
powershuf l'a fait en 0,047 seconde
La raison pour laquelle il est si rapide, eh bien je ne lis pas tout le fichier et je déplace simplement le pointeur de fichier 10 fois et j'imprime la ligne après le pointeur.
Gitlab Repo
Vieille tentative
J'ai d'abord eu besoin d'un fichier de 78.000.000.000 lignes:
Cela me donne un fichier avec 78 milliards de nouvelles lignes ;-)
Maintenant pour la partie shuf:
Le goulot d'étranglement était CPU et n'utilisant pas plusieurs threads, il a épinglé 1 cœur à 100%, les 15 autres n'ont pas été utilisés.
Python est ce que j'utilise régulièrement, c'est ce que j'utiliserai pour accélérer les choses:
Cela m'a pris un peu moins d'une minute:
Je l'ai fait sur un Lenovo X1 extreme 2nd gen avec l'i9 et le Samsung NVMe, ce qui me donne beaucoup de vitesse de lecture et d'écriture.
Je sais que ça peut aller plus vite mais je vais laisser de la place pour essayer les autres.
Compteur de ligne source: Luther Blissett
la source