encontrar + grep
Use o comando find
find /that/directory -type f -exec sha1sum {} \; | grep 'known sha1 sum'
A maneira como isso funciona é a seguinte:
-
find
operará recursivamente em/that/directory
-
-type f
nos permite filtrar somente arquivos regulares -
exec sha1sum {} \;
executará o comandosha1sum
com cada arquivo como argumento (que é o que significa{}
entre colchetes) -
grep 'known sha1sum'
nos permite filtrar a saída do comandofind
para obter a linha de saída com o hashsum sha1 que precisamos.
globstar do Bash
Outra coisa que pode ser feita, é usar bash
de globstar
para habilitar a globalização recursiva e iterar dessa maneira. Aqui está como eu procuraria por um arquivo com sha1sum conhecido
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
Em vez de iterar via loop, podemos tornar isso ainda mais curto:
bash-4.3$ shopt -s globstar
bash-4.3$ sha1sum ./**/* 2>/dev/null | grep '4b1e65aab01f76b8863707eda5215af09633d275'4b1e65aab01f76b8863707eda5215af09633d275 ./golang/hello_world
Embora esse método possa ser curto, eu seria cético em relação a esse método em um diretório com grande quantidade de arquivos, em que glob poderia expandir fora do intervalo de quantidade máxima de argumentos de linha de comando. Emptor de advertência
Python 3
Claro que, sendo um aficionado pelo Python, eu não poderia sair sem fornecer um script python para essa tarefa. Esse script usa vários argumentos, portanto você pode especificar vários sha1sums que você precisa localizar, o que se alinha ao requisito da pergunta para executar essa tarefa em vários arquivos.
Observe que o script supõe que você deseja pesquisar do diretório de trabalho atual até os subdiretórios, portanto, assegure-se de ter cd
no diretório principal desejado
#!/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()
Execução de teste:
$ ./find_with_sha1.py '4b1e65aab01f76b8863707eda5215af09633d275' '38ab29bdda161da8082cbbc97d33747dff6fb848'
4b1e65aab01f76b8863707eda5215af09633d275 ./golang/hello_world
38ab29bdda161da8082cbbc97d33747dff6fb848 ./golang/hello_world.go
Este script também está disponível no meu repositório do GitHub pessoal, onde mais detalhes e alterações serão adicionados a este script.