Je dois trouver un fichier spécifique avec une somme sha1 connue. Je sais dans quel dossier le fichier devrait être, mais il y a des sous-dossiers (jusqu'à la profondeur maximale 4). Je connais plus ou moins des parties du nom de fichier (contient les mots "projet" et "screenshoot"), mais il existe différents formats de fichiers possibles (.ods, .docx, .pdf ...). Et bien sûr, je sais quelle somme il a. Comment le trouver?
Je dois le faire pour environ 15 fichiers.
Utiliser la commande de recherche
find /that/directory -type f -exec sha1sum {} \; | grep 'known sha1 sum'
La façon dont cela fonctionne est la suivante:
find
fonctionnera de manière récursive sur /that/directory
-type f
nous permet de filtrer uniquement les fichiers normauxexec sha1sum {} \;
exécutera la commande sha1sum
avec chaque fichier en tant qu'argument (ce que signifie {}
entre crochets)grep 'known sha1sum'
nous permet de filtrer la sortie de la commande find
pour obtenir la ligne de sortie avec le hashs sha1 dont nous avons besoin.Une autre chose à faire consiste à utiliser bash
'globstar
pour activer la suppression récursive et à l'itérer de cette façon. Voici comment je chercherais un fichier avec sha1sum 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 la boucle for, nous pouvons rendre cela 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 se développer en dehors de la plage de la quantité maximale d'arguments de ligne de commande. Caveat emptor
Bien sûr, étant un passionné de Python, je ne pouvais pas partir sans fournir un script python pour cette tâche. Ce script prend plusieurs arguments, vous pouvez donc spécifier plusieurs sommes sha1 que vous devez rechercher, ce qui est conforme à l'exigence de la question pour pouvoir effectuer cette tâche sur plusieurs fichiers.
Notez que le script suppose que vous souhaitez effectuer une recherche dans le répertoire de travail actuel vers les sous-répertoires. Assurez-vous donc de commencer par cd
#!/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 __== '__main__': main()
Essai:
$ ./find_with_sha1.py '4b1e65aab01f76b8863707eda5215af09633d275' '38ab29bdda161da8082cbbc97d33747dff6fb848'
4b1e65aab01f76b8863707eda5215af09633d275 ./golang/hello_world
38ab29bdda161da8082cbbc97d33747dff6fb848 ./golang/hello_world.go
Ce script est également disponible sur mon dossier personnel référentiel GitHub , où des développements et des modifications supplémentaires seront ajoutés à ce script.
Que diriez-vous d'une combinaison de find
, sha1sum
et grep
:
find . -maxdepth 4 -type f | xargs -IF sha1sum "F" | grep 83976c8060222298565fd434c64ee09d19733559