Tengo un directorio que contiene cientos de miles de archivos.
Necesito enumerar una muestra de estos archivos (por ejemplo, 10 archivos), sin procesar todos los archivos que se encuentran en el directorio, lo que tomará demasiado tiempo de procesamiento.
Respuesta1
No creo que puedas tomar muestras de toda la lista de archivos sin leerlos todos de una forma u otra, incluso a nivel del sistema de archivos.
A menos quesus nombres siguen un patrón (por ejemplo, archivoXXXXXXX), en cuyo caso podría pregenerar una lista aleatoria de nombres antes de acceder a los archivos. Para una cantidad tan grande de archivos, sería extraño que sus nombres fueran aleatorios.
Pero supongamos que no tienes tanta suerte. find
Se prefiere el uso a ls
, ya que puede escapar de la salida con nulo, lo que lo hace inmune a caracteres no estándar en los nombres de archivos. Si no queremos leer todos los archivos, lo más rápido es utilizar los que están al inicio del listado. Para obtener una mejor muestra, primero usaría una muestra más grande ( $oversamplesize
a continuación) y luego haría una subselección aleatoria de tamaño $samplesize
a partir de ahí. No logré crear sort -R
ni shuf
trabajar bien con separadores nulos, por lo que la mezcla y la selección final se realizan mediante awk
:
find ~ -type f -print0 |
grep --null --null-data -m ${oversamplesize:-100} . |
awk -v samplesize=${oversamplesize:-11} -vRS='\0' -vORS='\0' \
'{ a[NR]=$0 } END {srand(); while (i<samplesize) { b=(int(rand()*10000)%samplesize); if (b in c) {continue;} else {c[b]=a[b]; print a[b]; i++;} }; }' |
xargs -0 echo # echo here being just a dummy
Dos notas aquí. Por alguna razón, a menudo también imprime un nombre de archivo vacío, así que aumenté el tamaño de la muestra por si acaso. La nota trivial es no olvidar cambiar la ruta de búsqueda (~ aquí) y el comando final.