¿Cómo md5 una lista de rutas de archivo contenidas en un archivo?

Tengo una carpeta que contiene muchas carpetas que contienen muchos archivos. Miles.

Puedo hacer find . -type f > ./FILE-LISTING.TXTpara crear un archivo que contenga muchos miles de rutas de archivo que se vea así:

./Anders/Letters/20190101 Rent.pdf
./Anders/Letters/20190103 Appeal.pdf
./Anders/Letters/20190107 Decision.pdf
./Beeker/Letters/20180101 Rent.pdf

¿Cómo alimentaría esa lista de rutas de archivo md5para producir una salida con el formato siguiente?

9cf14e4d666dcb6aab17763b02429a19 ./Anders/Letters/20190101 Rent.pdf
d1bb70baa31f1df69628c00632b65eab ./Anders/Letters/20190103 Appeal.pdf
7a0f5bc18688fe8ba32f43aa6ec53fb1 ./Anders/Letters/20190107 Decision.pdf
a0c96a79cf3b1847025d9f073151519d ./Beeker/Letters/20180101 Rent.pdf

NB: quiero los hash md5 de los archivos a los que se hace referencia, no el md5 de la lista de archivos, ni los hash md5 de las cadenas en el file-listing.txt.

Además, ¿sería más rápido hacerlo todo en una línea de comando, o hacerlo en dos pasos ( findpara crear file-listing.txt, luego md5para crear file-listing-md5.txt)?

Esta es una excelente pregunta: claro, plantea algunos desafíos, pero será muy factible ya que cada herramienta de automatización en MacOS necesita manejar espacios en los nombres de archivo, bucles y variables para manejar el archivo cambiante que se procesa. Bien hecho. Espero que obtengamos excelentes respuestas en python, bash, swift y otras opciones para secuencias de comandos.
¿Cuál es su caso de uso para este archivo? mtreees una herramienta ya disponible para monitorear hashes de archivos y detectar cambios en nombres de archivos, contenidos de archivos, permisos o marcas de fecha. man mtreepara detalles.mtree -c -K md5digest
El caso de uso es entregar un archivo de hash y rutas de archivos a un RDBMS de terceros que rastrea muchos detalles adicionales que no están presentes en el sistema de archivos. Si los archivos se mueven, se pueden volver a vincular. Si el archivo se edita en su lugar, se puede volver a vincular.

Respuestas (2)

find . -type f -exec /sbin/md5 -r {} +
       ^^^^^^^ ^^^^^ ^^^^^^^^^^^^ ^^ ^
          |      |        |       |  |
          |      |        |       |  +- add as many file names as possible per call
          |      |        |       +---- replace with names of found files
          |      |        +------------ command to run
          |      +--------------------- execute following command
          +---------------------------- find any "normal" file

debería hacer el truco (y ocuparse de los problemas habituales con espacios, etc. dentro de los nombres de archivo).

En cuanto a más rápido: un pase casi siempre es más rápido que dos pases. En el caso específico, el cálculo de MD5 toma tanto tiempo que probablemente se puedan ignorar otros factores.

PD: Punta del sombrero a @lhf por recordarme-r

Tanto @nohillside como @lhf proporcionaron respuestas buenas y válidas. Por un capricho, decidí ver si uno es sustancialmente mejor que el otro. Ejecuté ambos en un directorio que contenía más de 64.000 archivos en time. La find -execversión era unos 3 segundos más rápida que find | xargs. Sin embargo, el tiempo de ejecución para ambos fue de alrededor de 45 segundos, lo que significa que (a) la diferencia es inferior al 10 % y (b) el tiempo probablemente esté limitado por E/S (imprimiendo en la consola).
Es casi seguro que esto está vinculado a E / S (pero no para imprimir en la consola, tiene que digerir todos esos archivos, eso llevará tiempo)
@CraigS.Cottingham Hay tantos archivos, pero en directorios profundamente anidados, no solo en un directorio, lo que podría explicar por qué la línea de comandos que heredé tarda unos 15 minutos en ejecutarse. La próxima vez que esté en el sitio, también haré una comparación.
Los comandos de búsqueda simple de @Erics (como el que tiene en la pregunta) están puramente vinculados a E/S. Al calcular también los hash MD5, podría ser E/S (para leer todos los datos) o CPU (para calcular el hash), pero esto depende del hardware utilizado.

Prueba esto:

find . -type f -print0 | xargs -0 md5 -r

Tenga en cuenta -print0y -0para manejar los espacios en los nombres de archivo.

En comparación con find . -type f -exec, esta solución se ejecuta md5con mucha menos frecuencia, aunque es posible que esto no tenga un impacto medible.

find's -exec {}también puede manejar espacios en los nombres de archivo.
Tanto @nohillside como @lhf proporcionaron respuestas buenas y válidas. Por un capricho, decidí ver si uno es sustancialmente mejor que el otro. Ejecuté ambos en un directorio que contenía más de 64.000 archivos en time. La find -execversión era unos 3 segundos más rápida que find | xargs. Sin embargo, el tiempo de ejecución para ambos fue de alrededor de 45 segundos, lo que significa que (a) la diferencia es inferior al 10 % y (b) el tiempo probablemente esté limitado por E/S (imprimiendo en la consola).
¿Qué caparazón estás usando?
@fd0, estoy usando bash.