En un script Bash, quiero seleccionar N líneas aleatorias del archivo de entrada y salida a otro archivo.
¿Cómo se puede hacer esto?
bash
shell
random
text-processing
usuario121196
fuente
fuente
sort -R
ya que hace mucho trabajo en exceso, especialmente para archivos largos. Se puede utilizar$RANDOM
,% wc -l
,jot
,sed -n
(a la stackoverflow.com/a/6022431/563329 ), y la funcionalidad de bash (matrices, redirecciones de mando, etc.) para definir su propiapeek
función que en realidad se ejecutará en los archivos de 5.000.000 línea.Respuestas:
Use
shuf
con la-n
opción que se muestra a continuación para obtenerN
líneas aleatorias:fuente
sort -R
?Ordene el archivo al azar y elija las primeras
100
líneas:fuente
sort
en realidad ordena líneas idénticas juntas, por lo que si puede tener líneas duplicadas y tieneshuf
(una herramienta gnu) instalada, es mejor usarla para esto.shuf -n
actúa de manera bastante instantánea.sort -R
es probablemente la opción GNU, instale GNU coreutils. por cierto,shuf
también es parte de coreutils.sort -R input | head -n <num_lines>
. El archivo de entrada tenía 279 GB, con 2bi + líneas. Sin embargo, no puedo compartirlo. De todos modos, el punto es que puedes mantener algunas líneas en la memoria con shuffle para hacer la selección aleatoria de qué generar. Ordenar ordenará todo el archivo, independientemente de cuáles sean sus necesidades.Bueno, según un comentario sobre la respuesta de shuf, barajó 78 000 000 000 líneas en menos de un minuto.
Desafío aceptado...
EDITAR: batí mi propio récord
powershuf lo hizo en 0.047 segundos
La razón es que es tan rápido, bueno, no leo todo el archivo y simplemente muevo el puntero del archivo 10 veces e imprimo la línea después del puntero.
Gitlab Repo
Viejo intento
Primero necesitaba un archivo de 78,000,000,000 líneas:
Esto me da un archivo con 78 mil millones de nuevas líneas ;-)
Ahora para la parte shuf:
El cuello de botella era CPU y no usaba múltiples hilos, fijó 1 núcleo al 100% y los otros 15 no se usaron.
Python es lo que uso regularmente, así que eso es lo que usaré para hacer esto más rápido:
Esto me consiguió poco menos de un minuto:
Hice esto en un Lenovo X1 extreme 2nd gen con el i9 y Samsung NVMe, lo que me da mucha velocidad de lectura y escritura.
Sé que puede ser más rápido, pero dejaré espacio para intentarlo.
Fuente del contador de línea : Luther Blissett
fuente