джакузи не очень распространенный хэш. Вам, вероятно, придется установить программу для его вычисления. например Debian / Ubuntu включают пакет «джакузи». Программа сама печатает хеш одного файла. apt-cache search whirlpool показывает, что некоторые другие пакеты поддерживают его, включая интересный md5deep.
Некоторые из более ранних anwsers не будут работать с именами файлов с пробелами в них. Если это так, но в ваших файлах нет новых строк в имени файла, вы можете смело использовать \ n в качестве разделителя.
oldifs="$IFS"
IFS="
"
for i in $(find -type f); do echo "$i";done
#output
# ./base
# ./base2
# ./normal.ext
# ./trick.e "xt
# ./foo bar.dir ext/trick' (name "- }$foo.ext{}.ext2
IFS="$oldifs"
попробуйте без установки IFS, чтобы понять, почему это важно.
Я собирался что-то попробовать с IFS = "."; найти -print0 | при чтении массива, разделить на "." символы, но я обычно никогда не использую переменные массива. На странице руководства нет простого способа вставить хеш в качестве второго по порядку индекса массива и сдвинуть последний элемент (расширение файла, если оно имело место). Каждый раз, когда переменные массива bash выглядят интересно, я знаю, пришло время делать то, что я делаю в Perl! Посмотрите ошибки для использования читать:
http://tldp.org/LDP/abs/html/gotchas.html#BADREAD0
Я решил использовать другую технику, которая мне нравится: find -exec sh -c. Это самый безопасный способ, поскольку вы не анализируете имена файлов.
Это должно сработать:
find -regextype posix-extended -type f -not -regex '.*\.[a-fA-F0-9]{128}.*' \
-execdir bash -c 'for i in "${@#./}";do
hash=$(whirlpool "$i");
ext=".${i##*.}"; base="${i%.*}";
[ "$base" = "$i" ] && ext="";
newname="$base.$hash$ext";
echo "ext:$ext $i -> $newname";
false mv --no-clobber "$i" "$newname";done' \
dummy {} +
# take out the "false" before the mv, and optionally take out the echo.
# false ignores its arguments, so it's there so you can
# run this to see what will happen without actually renaming your files.
-execdir bash -c 'cmd' dummy {} + содержит там фиктивный аргумент, потому что первый аргумент после команды становится $ 0 в позиционных параметрах оболочки, а не частью "$ @", что для циклов over. Я использую execdir вместо exec, поэтому мне не нужно иметь дело с именами каталогов (или возможностью превышения PATH_MAX для вложенных директорий с длинными именами, когда фактические имена файлов достаточно короткие).
-not -regex предотвращает его применение дважды к одному и тому же файлу. Хотя Whirlpool - это очень длинный хеш, и mv говорит, что имя файла слишком длинное, если я запускаю его дважды без этой проверки. (в файловой системе XFS.)
Файлы без расширения получают basename.hash. Я должен был проверить специально, чтобы избежать добавления трейлинга или получения базового имени в качестве расширения. $ average@#./} удаляет ведущий ./, который находит перед каждым именем файла, так что "." во всей строке для файлов без расширения.
mv --no-clobber может быть расширением GNU. Если у вас нет GNU mv, сделайте что-нибудь еще, если вы хотите избежать удаления существующих файлов (например, если вы запустите его один раз, некоторые из этого же файла будут добавлены в каталог со старыми именами; вы запустите его снова.) если ты хочешь такое поведение, просто убери его.
Мое решение должно работать, даже если имена файлов содержат новую строку (они могут, вы знаете!) Или любой другой возможный символ. Это будет быстрее и проще в Perl, но вы попросили shell.
Решение wallenborn для создания одного файла со всеми контрольными суммами (вместо переименования оригинала) довольно хорошее, но неэффективное. Не запускайте md5sum один раз для каждого файла, запустите его одновременно на столько файлов, сколько поместится в его командной строке:
find dir -type f -print0 | xargs -0 md5sum> dir.md5
или с помощью GNU find встроен xargs (обратите внимание на + вместо ';')
find dir -type f -exec md5sum {} +> dir.md5
, если вы просто используете find -print | xargs -d '\ n', вы будете испорчены именами файлов с кавычками, так что будьте осторожны. Если вы не знаете, с какими файлами вы можете когда-нибудь запустить этот скрипт, всегда старайтесь использовать print0 или -exec. Это особенно. Значение true, если имена файлов предоставляются ненадежными пользователями (т. е. может быть вектором атаки на вашем сервере.)