Генерация случайной строки zsh
Я пытаюсь сгенерировать случайную строку со следующим кодом:
for pic in `ls *.jpg`; do
rdn=`echo $RANDOM | sha256sum | cut -d" " -f1`
mv "$pic" ${rnd}.jpg
done
Эта часть скрипта запускается из каталога, содержащего множество файлов JPEG, и она должна рандомизировать их имена файлов. Проблема в том, что $RANDOM
переменная не обновляется во время итерации, поэтому каждый раз выдает один и тот же хэш. Я пытался использовать /dev/urandom
и это работает, но намного медленнее, чем $RANDOM
, Что я могу сделать, чтобы "восстановить" $RANDOM
каждый раз это читается?
3 ответа
for pic in *.jpg; do # Iterate over the jpgs in the current directory.
dd if=/dev/urandom count=1 2>/dev/null | sha256sum | ( # Gather 512 bytes from /dev/urandom
read rnd _ # Read the first "word" in the sha256sum output
mv "$pic" ${rnd}.jpg # rename the jpg.
)
done
Трубопровод к read
вызывает неявную подоболочку, поэтому я создаю явную подоболочку, чтобы гарантировать доступ к rnd
параметр. Кроме того, не разбирайте ls
Кстати, вы уверены, что не хотите просто base64
выход? Это намного дешевле, чем sha256sum, и я не вижу, что вы получаете от sha256sum. Кроме того, это облегчит чтение кода:
for pic in *.jpg; do
mv "$pic" "$(base64 </dev/urandom | tr -dc 'a-zA-Z0-9' | head -c20).jpg"
done
На моем Mac (с использованием MacOS High Sierra) /dev/urandom
дает мне двоичные байты, поэтому приведенное выше решение приводит к tr: Illegal byte sequence
так я использовал base64
преобразовать байты в символы:
cat /dev/urandom | base64 | tr -dc '0-9a-zA-Z' | head -c100
или я нашел решение без base64, чтобы вы могли также получить знаки препинания:
cat /dev/urandom | LC_ALL=C tr -dc '\''[:alnum:]\!\@\#$\-\.\,'\'' | head -c40
Вы можете сделать это более просто, используя cat, tr и head. Например:
cat /dev/urandom | tr -dc '0-9a-zA-Z' | head -c100
tr
Команда в этом конвейере удалит любой символ из стандартного ввода, который не соответствует указанному набору символов. head
напечатает первые 100 символов и затем выйдет, завершив общую команду.
Это сгенерирует 100-символьную строку, содержащую буквенно-цифровые символы. Чтобы сделать это в переименовании, вам просто нужно использовать подстановку команд:
for file in *.jpg
mv -n ${file} $(cat /dev/urandom | tr -dc '0-9a-zA-Z' | head -c100).jpg
В зш а for
цикл с одним утверждением не должен быть окружен do
или же done
, -n
flag to mv предотвратит перезапись существующего файла - на тот случай, если вам действительно не повезет со случайными строками.