find + grep
Utilisez la commande find
find /that/directory -type f -exec sha1sum {} \; | grep 'known sha1 sum'
Le fonctionnement est le suivant :
-
find
opérera de manière récursive sur /that/directory
-
-type f
nous permet de filtrer uniquement les fichiers réguliers
-
exec sha1sum {} \;
effectuera sha1sum
avec chaque fichier comme argument ( ce qui est ce que la commande {}
Les parenthèses signifient )
-
grep 'known sha1sum'
nous permet de filtrer la sortie de find
pour obtenir la ligne de sortie avec le hashsum sha1 dont nous avons besoin.
L'étoile globulaire de Bash
Une autre chose qui pourrait être faite, est d'utiliser bash
's globstar
pour activer le globbing récursif, et itérer de cette façon. Voici comment je rechercherais un fichier dont le sha1sum est connu
bash-4.3$ shopt -s globstar ;
bash-4.3$ known_sha1sum="4b1e65aab01f76b8863707eda5215af09633d275"
bash-4.3$ for f in ./**/* ; do [ -f "$f" ] && shasum=$(sha1sum "$f" | awk '{print $1}'); [ "$shasum" = "$known_sha1sum" ] && echo "$f"; done
./golang/hello_world
Au lieu d'itérer via boucle for, on peut faire encore plus court :
bash-4.3$ shopt -s globstar
bash-4.3$ sha1sum ./**/* 2>/dev/null | grep '4b1e65aab01f76b8863707eda5215af09633d275'4b1e65aab01f76b8863707eda5215af09633d275 ./golang/hello_world
Bien que cette méthode puisse être courte, je serais sceptique quant à cette méthode sur un répertoire avec une grande quantité de fichiers, où glob pourrait s'étendre en dehors de la plage de la quantité maximale d'arguments de ligne de commande. Caveat emptor
Python 3
Bien sûr, étant un aficionado de Python, je ne pouvais pas partir sans fournir un script Python pour cette tâche. Ce script prend plusieurs arguments, de sorte que vous pouvez spécifier plusieurs sha1sums que vous devez trouver, ce qui s'aligne sur l'exigence de la question pour effectuer cette tâche pour plusieurs fichiers.
Notez que le script suppose que vous souhaitez effectuer une recherche à partir du répertoire de travail actuel jusqu'aux sous-répertoires, donc assurez-vous que vous cd
au répertoire supérieur souhaité en premier
#!/usr/bin/env python3
import os
import sys
from hashlib import sha1
def get_sha1sum(file_path):
sha1sum = sha1()
with open(file_path, 'rb') as fd:
data_chunk = fd.read(1024)
while data_chunk:
sha1sum.update(data_chunk)
data_chunk = fd.read(1024)
return str(sha1sum.hexdigest())
def find_files(treeroot):
for dir,subdirs,files in os.walk(treeroot):
for f in files:
full_path = os.path.join(dir,f)
path_sha1sum = get_sha1sum( full_path )
if path_sha1sum in sys.argv[1:]:
print(path_sha1sum,full_path)
def main():
find_files('.')
if __name__ == '__main__': main()
Test de fonctionnement :
$ ./find_with_sha1.py '4b1e65aab01f76b8863707eda5215af09633d275' '38ab29bdda161da8082cbbc97d33747dff6fb848'
4b1e65aab01f76b8863707eda5215af09633d275 ./golang/hello_world
38ab29bdda161da8082cbbc97d33747dff6fb848 ./golang/hello_world.go
Ce script est également disponible sur mon site personnel. Dépôt GitHub où d'autres développements et modifications seront ajoutés à ce script.