2013-10-24 3 views
2

Я пытаюсь создать случайную строку со следующим кодом:генерации случайных строк ЗШ

for pic in `ls *.jpg`; do 
    rdn=`echo $RANDOM | sha256sum | cut -d" " -f1` 
    mv "$pic" ${rnd}.jpg 
done 

Эта часть сценария проходит внутри каталога, содержащего множество файлов в формате JPEG, и это должно рандомизации их имена файлов. Проблема в том, что переменная $RANDOM не обновляется во время итерации и поэтому каждый раз дает один и тот же хэш. Я пытался использовать /dev/urandom, и он работает, но намного медленнее, чем $RANDOM. Что я могу сделать, чтобы «восстановить» $RANDOM каждый раз, когда он читается?

+0

Работы для меня .. Если это скрипт, убедитесь, что строка shebang говорит «/ bin/bash» вместо «/ bin/sh», на всякий случай. – vanza

+0

Что вы пытались использовать/dev/urandom? Например, если вы ограничиваете срез 'dd', это должно быть довольно быстро. – kojiro

+0

Кроме того, эта строка из руководства bash может быть релевантной: * Если RANDOM не настроен, он теряет свои особые свойства, даже если он впоследствии будет сброшен. * – kojiro

ответ

1
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 

Piping к read вызывает неявную подоболочку, поэтому я создаю явную подоболочку, чтобы гарантировать, я все еще могу получить доступ к параметру rnd. Кроме того, don't parse ls

Кстати, вы уверены, что хотите не только base64 выход? Это дешевле, чем sha256sum, и я не вижу, что вы получаете из sha256sum. Плюс это сделало бы код более удобным для чтения:

for pic in *.jpg; do 
    mv "$pic" "$(base64 </dev/urandom | tr -dc 'a-zA-Z0-9' | head -c20).jpg" 
done 
+0

Работает очень красиво. Благодарю. – wafel

4

Вы можете сделать это проще, просто используя 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 

В Zsh for цикл с помощью одного оператора не должны быть окружены do или done. Флаг -n в mv не позволит ему переписать существующий файл - на случай, если вам действительно не повезло со случайными строками.

0

На мой макинтош (используя Macos High Sierra), то /dev/urandom дает мне двоичных байт, так что приведенные выше результаты решения в tr: Illegal byte sequence, поэтому я использовал base64 для преобразования байтов в символы:

cat /dev/urandom | base64 | tr -dc '0-9a-zA-Z' | head -c100 
Смежные вопросы