Как рассчитать хеш для строки (URL) в Bash для кэширования Wget - PullRequest
15 голосов
/ 21 октября 2009

Я создаю небольшой инструмент, который будет загружать файлы с помощью wget, читая ссылки из разных файлов. Один и тот же URL может присутствовать в разных файлах; URL может даже присутствовать в одном файле несколько раз. Было бы неэффективно загружать страницу несколько раз (каждый раз, когда ее URL-адрес находился в списке (ах)).

Таким образом, простой подход состоит в том, чтобы сохранить загруженный файл и дать команду wget не загружать его снова, если он уже существует.

Это было бы очень просто; однако URL-адреса очень длинные (многие параметры GET) и поэтому не могут использоваться как таковые для имен файлов (wget выдает ошибку «Невозможно записать в ... [] имя файла слишком длинное»).

Итак, мне нужно переименовать загруженные файлы. Но для того, чтобы механизм кэширования работал, схема переименования должна реализовывать «один URL <=> одно имя»: если данный URL может иметь несколько имен, кэширование не работает (т. Е. Если я просто нумерую файлы в порядке они найдены, я не позволю wget определить, какие URL уже были загружены).

Простейшей схемой переименования было бы вычисление хеша md5 имени файла , а не самого файла, что и делает md5sum); это обеспечило бы уникальность имени файла и то, что данный URL всегда будет иметь одинаковое имя.

Это можно сделать в Perl и т. Д., Но можно ли это сделать непосредственно в bash или с помощью системной утилиты (RedHat)?

Ответы [ 4 ]

28 голосов
/ 21 октября 2009

Звучит так, как будто вам нужна системная утилита md5sum.

URLMD5=`/bin/echo $URL | /usr/bin/md5sum | /bin/cut -f1 -d" "`

Если вы хотите создать хэш только для имени файла, вы можете получить это быстро с помощью sed:

FILENAME=`echo $URL | /bin/sed -e 's#.*/##'`
URLMD5=`/bin/echo $FILENAME | /usr/bin/md5sum | /bin/cut -f1 -d" "`

Обратите внимание, что в зависимости от вашего дистрибутива путь к cut может быть /usr/bin/cut.

10 голосов
/ 19 ноября 2011

У меня нет представителя, чтобы комментировать ответ, но есть одно уточнение к ответу Epsilon Prime: по умолчанию echo будет печатать новую строку в конце текста. Если вы хотите, чтобы суммы md5 соответствовали тому, что будет сгенерировано любым другим инструментом (например, php, Java md5 и т. Д.), Вам нужно вызвать

echo -n "$url"

, который подавит перевод строки.

6 голосов
/ 06 июня 2015

Другие опции на моем Ubuntu (Precise) box:

  • echo -n $STRING | sha512sum
  • echo -n $STRING | sha256sum
  • echo -n $STRING | sha224sum
  • echo -n $STRING | sha384sum
  • echo -n $STRING | sha1sum
  • echo -n $STRING | shasum

Другие параметры на моем Mac:

  • echo -n $STRING | shasum -a 512
  • echo -n $STRING | shasum -a 256
  • и т.д.
1 голос
/ 21 октября 2009

Более новые версии Bash предоставляют ассоциативный массив, а также индексированный массив. Нечто подобное может работать для вас:

declare -A myarray
myarray["url1"]="url1_content"
myarray["url2"]=""

if [ ! -z ${myarray["url1"]} ] ; then 
    echo "Cached";
fi

wget обычно переименовывает файлы с именем filename.html.1, .2 и т. Д., Так что вы можете использовать ассоциативный массив для хранения списка того, какой из них был загружен и какое имя файла имело место.

...