Calcular sumas de verificación para una selección aleatoria de archivos cuyos nombres aparecen en un archivo

Calcular sumas de verificación para una selección aleatoria de archivos cuyos nombres aparecen en un archivo

Digamos que tengo un archivo llamado list_of_files.txtdonde cada línea corresponde a un archivo en el disco. Por ejemplo:

dir1/fileA.ext1
dir1/subdir1/fileB.ext2
fileC.ext3
dir2/fileD.ext4
fileE.ext5

Quiero seleccionar aleatoriamente una cantidad de archivos de esa lista y cksumcalcularlos md5sum.

Sé que puedo seleccionar aleatoriamente, digamos, 3 archivos con shuf -n 3 list_of_files.txt, pero ¿cómo puedo cksumtratarlos como nombres de archivos en lugar de contenido de texto?

Respuesta1

Si las rutas del archivo terminan en una nueva línea y se proporcionan tal como están, es decir, si cada línea es una ruta literal separada, entonces un bucle de shell funcionará:

shuf -n 3 list_of_files.txt | while IFS= read -r pth; do
   cksum "$pth"
done

También hay xargs(ver elespecificación POSIXy más avanzadoÑUxargs), hayÑUparallel(notaparallelexiste no-GNUy no me refiero a eso). Con la herramienta adecuada y las opciones adecuadas, puede hacer que un cksumproceso tenga más de una ruta ( cksumen general, generar menos procesos es beneficioso) o ejecutar dos o más cksumprocesos en paralelo.

Para procesar tan solo tres archivos, puedo ceñirme a nuestro bucle de shell debido a la portabilidad; a menos que los archivos sean grandes y espero que tres cksumprocesos que se ejecutan en paralelo sean sustancialmente más rápidos que uno cksuma la vez. No soy un experto en GNU parallel, pero parece que la solución es tan simple como:

 shuf -n 3 list_of_files.txt | parallel cksum

De forma predeterminada, GNU parallellimita la cantidad de trabajos simultáneos según la cantidad de núcleos de CPU. Hoy en día son comunes tres o más núcleos, por lo que el comando probablemente ejecutará tres cksumprocesos en paralelo. Sin embargo, formalmente esto no es portátil. También tenga en cuenta que procesar tres archivos en paralelo significa leer tres archivos en paralelo. La E/S puede ser un cuello de botella y esto puede reducir el beneficio de los trabajos paralelos o incluso empeorar las cosas.

Incluso entonces parallelpuede resultar útil. Utilícelo -j 1para limitar el número de trabajos a 1:

 shuf -n 3 list_of_files.txt | parallel -j 1 cksum

Los archivos se procesarán secuencialmente como en nuestro bucle de shell, pero la sintaxis es más simple. En el caso de nuestro bucle Shell, necesita saber que deseaIFS= read -r pth, No solo read pth; y necesitas saber que (en muchos aspectos) quierescksum "$pth", no cksum $pth. La solución con GNU paralleles menos propensa a errores.BESO.

De forma predeterminada, Note xargsinterpreta las comillas y las barras invertidas y considera los espacios como delimitadores. Probablemente este medio shuf -n 3 list_of_files.txt | xargs cksumno sea lo que desea. Su ejemplo funcionará, pero en general necesita comillas y/o barras invertidas adicionales en el archivo; xor necesitas xargs -d '\n'dónde -dhay una opción no portátil de GNU xargs. Mi suposición era que "las rutas del archivo terminan en una nueva línea y se proporcionan tal cual". Con esta suposición, GNU parallelfunciona de inmediato (es decir, sin opciones adicionales), xargs no. Con GNU xargspuedes hacer esto:

shuf -n 3 list_of_files.txt | xargs -d '\n' cksum

Si puedes usar GNU xargs(para salvar el día -d '\n'), entonces probablemente puedas usar GNU parallel. Si lo olvida -j 1al usar GNU parallel, el comando puede funcionar peor pero seguirá funcionando. Si olvida -d '\n'cuando usa GNU xargsy los nombres de ruta se proporcionan tal como están, entonces es un error. Por eso recomendé GNU parallelprimero.

GNU paralelo es capaz de procesar cadenas terminadas en nulo (la opción es -0), al igual que GNU xargs( -0en lugar de -d '\n') y GNU shuf(con -z). Su archivo de entrada utiliza líneas terminadas en nueva línea, pero si alguna vez necesita trabajar con nombres de ruta que (pueden) contener caracteres de nueva línea, entonces cambiar el terminador en el archivo y agregar las opciones adecuadas es el camino a seguir.

información relacionada