Как вычислить хэш строки (url) в bash для кэширования wget
Вопрос
Я создаю небольшой инструмент, который будет загружать файлы с помощью wget, считывая URL-адреса из разных файлов.Один и тот же URL-адрес может присутствовать в разных файлах;URL-адрес может даже присутствовать в одном файле несколько раз.Было бы неэффективно загружать страницу несколько раз (каждый раз, когда ее URL-адрес обнаруживается в списке(ах)).
Таким образом, простой подход — сохранить загруженный файл и дать команду wget не загружать его снова, если он уже существует.
Это было бы очень просто;однако URL-адреса очень длинные (много параметров GET) и поэтому не могут использоваться как таковые для имен файлов (wget выдает ошибку «Невозможно записать в...[] имя файла слишком длинное').
Итак, мне нужно переименовать скачанные файлы.Но чтобы механизм кэширования работал, схема переименования должна реализовать «один URL <=> одно имя»:если данный URL-адрес может иметь несколько имен, кэширование не работает (т. е. если я просто нумерую файлы в том порядке, в котором они найдены, я не позволю wget определить, какие URL-адреса уже были загружены).
Простейшей схемой переименования будет вычисление хеша md5. имени файла (и нет самого файла, что и делает md5sum);это обеспечит уникальность имени файла и то, что заданный URL-адрес всегда будет иметь одно и то же имя.
Это можно сделать в Perl и т. д., но можно ли это сделать непосредственно в bash или с помощью системной утилиты (RedHat)?
Решение
Звучит так, будто вам нужна системная утилита 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
.
Другие советы
У меня нет представителя, чтобы комментировать ответ, но есть одно уточнение к ответу Epsilon Prime: по умолчанию echo будет печатать новую строку в конце текста. Если вы хотите, чтобы суммы md5 совпали с тем, что будет сгенерировано любым другим инструментом (например, php, Java md5 и т. Д.), Вам нужно вызвать
echo -n "$url"
который будет подавлять перевод строки.
Другие варианты в моем ящике Ubuntu (Precision):
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
- и т. д.
Более новые версии Bash предоставляют ассоциативный массив, а также индексированный массив , Нечто подобное может сработать для вас:
declare -A myarray
myarray["url1"]="url1_content"
myarray["url2"]=""
if [ ! -z ${myarray["url1"]} ] ; then
echo "Cached";
fi
wget обычно переименовывает файлы с именем filename.html.1, .2 и т. д., поэтому вы можете использовать ассоциативный массив для хранения списка того, какой из них был загружен, и каково было фактическое имя файла.