Поиск файла с известной суммой sha1

Я должен найти конкретный файл с известной суммой sha1. Я знаю, в какой папке должен быть файл, но есть подпапки (до макс. Глубины 4). Я знаю более или менее части имени файла (содержит слова "проект" и "снимок экрана"), но существуют различные возможные форматы файлов (.ods, .docx, .pdf ...). И, конечно, я знаю, какая у него сумма. Как это найти?

Я должен сделать это около 15 файлов.

2 ответа

Решение

найти + grep

Используйте команду поиска

find /that/directory -type f -exec sha1sum {} \; | grep 'known sha1 sum'

Это работает следующим образом:

  • find будет работать рекурсивно на /that/directory
  • -type f позволяет отфильтровывать только обычные файлы
  • exec sha1sum {} \; будет выполнять sha1sum команда с каждым файлом в качестве аргумента (что к чему {} скобки обозначают)
  • grep 'known sha1sum' позволяет нам фильтровать вывод find команда, чтобы получить строку вывода с хэш-суммой sha1, которая нам нужна.

Глобстар Баш

Другое, что можно сделать, это использовать bash"s globstar чтобы включить рекурсивное сглаживание и повторить этот путь. Вот как бы я искал файл с известным sha1sum

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

Вместо того, чтобы повторять цикл for, мы можем сделать это еще короче:

bash-4.3$ shopt -s globstar
bash-4.3$ sha1sum ./**/* 2>/dev/null | grep '4b1e65aab01f76b8863707eda5215af09633d275'4b1e65aab01f76b8863707eda5215af09633d275  ./golang/hello_world

Хотя этот метод может быть коротким, я скептически отношусь к этому методу в каталоге с большим количеством файлов, где glob может расширяться за пределы максимального количества аргументов командной строки. Пусть покупатель будет бдителен

Python 3

Конечно, будучи поклонником Python, я не мог уйти, не предоставив сценарий Python для этой задачи. Этот сценарий принимает несколько аргументов, поэтому вы можете указать несколько sha1sum, которые вам нужно найти, что соответствует требованию вопроса для выполнения этой задачи для нескольких файлов.

Обратите внимание, что в сценарии предполагается, что вы хотите выполнять поиск из текущего рабочего каталога в подкаталоги, поэтому убедитесь, что 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 __name__ == '__main__': main()

Тестовый забег:

$ ./find_with_sha1.py  '4b1e65aab01f76b8863707eda5215af09633d275' '38ab29bdda161da8082cbbc97d33747dff6fb848'      
4b1e65aab01f76b8863707eda5215af09633d275 ./golang/hello_world
38ab29bdda161da8082cbbc97d33747dff6fb848 ./golang/hello_world.go

Этот скрипт также доступен в моем личном репозитории GitHub, где дальнейшая разработка и изменения будут добавлены в этот скрипт.

Как насчет комбинации find, sha1sum а также grep:

find . -maxdepth 4 -type f | xargs -IF sha1sum "F" | grep 83976c8060222298565fd434c64ee09d19733559
Другие вопросы по тегам