Pregunta

necesito para calcular una suma de comprobación resumen MD5 para todos los archivos de un tipo determinado (por ejemplo *.py) incluidas en un directorio y todos los subdirectorios.

¿Cuál es la mejor manera de hacer eso?

Editar Las soluciones propuestas son muy agradables, pero esto no es exactamente lo que necesito. Estoy buscando una solución para conseguir un solo resumen suma de comprobación que identificará de forma única el directorio en su conjunto -. Incluyendo el contenido de todos sus subdirectorios

¿Fue útil?

Solución

find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum

El comando find listas de todos los archivos que terminan en .py. La suma md5 se calcula para cada archivo .py. awk se usa para escoger de los md5sums (ignorando los nombres de archivo, que puede no ser única). Los md5sums se ordenan. a continuación, se devuelve la suma md5 de esta lista ordenada.

He probado esta copiando un directorio de prueba:

rsync -a ~/pybin/ ~/pybin2/

Retitulé algunos de los archivos en ~ / pybin2.

El comando find...md5sum devuelve la misma salida para ambos directorios.

2bcf49a4d19ef9abd284311108d626f1  -

Otros consejos

Crear un archivo tar sobre la marcha y el tubo que a md5sum:

tar c dir | md5sum

Esto produce una sola md5sum que debe ser único para el archivo de configuración y subdirectorio. No se crean los archivos en el disco.

sugerencia de utilizar tar c <dir> de ire_and_curses tiene algunos problemas:

  • tar procesa las entradas de directorio en el orden en el que están almacenados en el sistema de archivos, y no hay manera de cambiar este orden. Esto efectivamente puede producir resultados completamente diferentes si usted tiene la "misma" directorio en diferentes lugares, y sé que no hay manera de solucionar este problema (alquitrán no puede ordenar sus archivos "" de entrada en un orden particular).
  • Por lo general importa si groupid y los números ID_PROPIETARIO son los mismos, no necesariamente si la representación de cadena de grupo / propietario es el mismo. Esto está en línea con lo que hace, por ejemplo, rsync -a --delete: sincroniza prácticamente todo (menos xattrs y ACL), pero se sincronizará propietario y el grupo sobre la base de su documento de identidad, no en representación de cadena. Así que si usted sincronizado a un sistema diferente que no necesariamente tienen los mismos usuarios / grupos, se debe añadir la bandera --numeric-owner al alquitrán
  • tar incluirá el nombre del archivo del directorio que se está comprobando en sí, pero es algo a tener en cuenta.

Mientras no hay una solución para el primer problema (o menos que esté seguro de que no le afecta), yo no usaría este enfoque.

Las soluciones basadas find propuestos anteriormente son también no es bueno, ya que sólo incluyen archivos, no directorios, que se convierte en un problema si la suma de comprobación debe tener en cuenta los directorios vacíos.

Por último, las soluciones sugeridas no lo hacen la mayoría especie consistente, ya que la colación podría ser diferente a través de sistemas.

Esta es la solución que se me ocurrió:

dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum

Notas acerca de esta solución:

  • El LC_ALL=C es para asegurar el orden de clasificación fiable a través de los sistemas
  • Esto no hace diferencia entre un directorio "llamado \ nwithanewline" y dos directorios "nombre" y "withanewline", pero la posibilidad de que occuring parece muy poco probable. Uno por lo general soluciona esto con una bandera -print0 para find pero ya que hay otras cosas que hacer aquí, sólo puedo ver soluciones que harían que el comando más complicado de lo que vale la pena.

PS: uno de mis sistemas utiliza una find busybox limitada que no admite ni banderas -exec -print0, y también se agrega '/' para denotar directorios, mientras que findutils encuentran no parece, por lo que para esta máquina que necesito ejecute:

dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum

Por suerte, no tengo los archivos / directorios con nuevas líneas en sus nombres, por lo que este no es un problema en ese sistema.

Si sólo se preocupan por los archivos y directorios no vacíos, esto funciona muy bien:

find /path -type f | sort -u | xargs cat | md5sum

En aras de la exhaustividad, hay md5deep (1) ; que no es directamente aplicable debido al requisito de filtro * .py, pero debe hacer bien en conjunto con find (1).

Una solución que funcionó mejor para mí:

find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum

Por lo que funcionó mejor para mí:

  1. maneja los nombres de archivo que contienen espacios
  2. No tiene en cuenta los sistemas de ficheros metadatos
  3. Detecta si el archivo ha cambiado de nombre

Problemas con otras respuestas:

Sistema de archivos de meta-datos no se tiene en cuenta para:

tar c - "$path" | md5sum

No maneja los nombres de archivo que contienen espacios ni detecta si el archivo ha cambiado de nombre:

find /path -type f | sort -u | xargs cat | md5sum

Si quieres uno md5sum que abarca todo el directorio, me gustaría hacer algo como

cat *.py | md5sum 

suma de comprobación de todos los archivos, incluyendo tanto el contenido como sus nombres de archivo

grep -ar -e . /your/dir | md5sum | cut -c-32

Igual que el anterior, pero sólo incluyendo archivos * .py

grep -ar -e . --include="*.py" /your/dir | md5sum | cut -c-32

También puede seguir enlaces simbólicos si desea

grep -aR -e . /your/dir | md5sum | cut -c-32

Otras opciones que podría considerar el uso con grep

-s, --no-messages         suppress error messages
-D, --devices=ACTION      how to handle devices, FIFOs and sockets;
-Z, --null                print 0 byte after FILE name
-U, --binary              do not strip CR characters at EOL (MSDOS/Windows)

GNU encontrar

find /path -type f -name "*.py" -exec md5sum "{}" +;

Técnicamente sólo tiene que ejecutar ls -lR *.py | md5sum. A menos que usted está preocupado por alguien modificación de los archivos y tocando de nuevo a sus fechas originales y nunca cambiar el tamaño de los ficheros, la salida de ls debe decirle si el archivo ha cambiado. Mi UNIX-foo es débil por lo que es posible que necesite un poco más parámetros de línea de comando para obtener la creación de tiempo y hora de modificación para imprimir. ls también le dirá si los permisos en los archivos han cambiado (y estoy seguro de que hay interruptores para apagar eso si no se preocupan por eso).

Yo uso HashCopy para hacer esto. Puede generar y verificar MD5 y SHA en un único archivo o un directorio. Se puede descargar desde www.jdxsoftware.org.

El uso de md5deep:

md5deep -r FOLDER | awk '{print $1}' | sort | md5sum

Yo tenía el mismo problema por lo que ocurrió con esta secuencia de comandos que simplemente enumera los md5sums de los archivos en el directorio y si encuentra un subdirectorio que se ejecuta de nuevo a partir de ahí, para que esto suceda el guión tiene que ser capaz de ejecutar a través del directorio actual o desde un subdirectorio si dicho argumento se pasa de $ 1

#!/bin/bash

if [ -z "$1" ] ; then

# loop in current dir
ls | while read line; do
  ecriv=`pwd`"/"$line
if [ -f $ecriv ] ; then
    md5sum "$ecriv"
elif [ -d $ecriv ] ; then
    sh myScript "$line" # call this script again
fi

done


else # if a directory is specified in argument $1

ls "$1" | while read line; do
  ecriv=`pwd`"/$1/"$line

if [ -f $ecriv ] ; then
    md5sum "$ecriv"

elif [ -d $ecriv ] ; then
    sh myScript "$line"
fi

done


fi

Si quieres realmente la independencia de los atributos del sistema de archivos y de las diferencias a nivel de bits de algunas versiones de alquitrán, se puede utilizar cpio:

cpio -i -e theDirname | md5sum

Hay dos soluciones más:

Crea:

du -csxb /path | md5sum > file

ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum > /tmp/file

Comprobar:

du -csxb /path | md5sum -c file

ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum -c /tmp/file

md5sum trabajado bien para mí, pero he tenido problemas con sort y clasificación de los nombres de archivo. Así que en vez ordenados por resultado md5sum. También necesitaba para excluir algunos archivos con el fin de crear resultados comparables.

find . -type f -print0 \ | xargs -r0 md5sum \ | grep -v ".env" \ | grep -v "vendor/autoload.php" \ | grep -v "vendor/composer/" \ | sort -d \ | md5sum

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top