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 -Rya 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 propiapeekfunción que en realidad se ejecutará en los archivos de 5.000.000 línea.Respuestas:
Use
shufcon la-nopción que se muestra a continuación para obtenerNlíneas aleatorias:fuente
sort -R?Ordene el archivo al azar y elija las primeras
100líneas:fuente
sorten 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 -nactúa de manera bastante instantánea.sort -Res probablemente la opción GNU, instale GNU coreutils. por cierto,shuftambié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