2013-10-24 213 views
2

我試圖生成與下面的代碼的隨機字符串:生成隨機字符串的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

+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 

管道到read導致一個隱含的子shell,所以我創建了一個明確的子shell,以保證我仍然可以訪問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循環用一個語句不需要與dodone包圍。 -n標誌mv將阻止它覆蓋現有的文件 - 以防萬一你真的不喜歡隨機字符串。

0

在我的Mac(使用MacOS的高塞拉利昂),該/dev/urandom給我的二進制字節,因此,上述解決方案導致tr: Illegal byte sequence,所以我用base64爲字節轉換成字符:

cat /dev/urandom | base64 | tr -dc '0-9a-zA-Z' | head -c100