我正在尝试使用以下代码生成一个随机字符串:
for pic in `ls *.jpg`; do
rdn=`echo $RANDOM | sha256sum | cut -d" " -f1`
mv "$pic" ${rnd}.jpg
done
Run Code Online (Sandbox Code Playgroud)
脚本的这部分从包含大量 jpeg 文件的目录中运行,它应该随机化它们的文件名。问题是$RANDOM变量在迭代过程中不会更新,因此每次都给出相同的哈希值。我尝试使用/dev/urandom,它可以工作,但比$RANDOM. $RANDOM每次阅读时我能做些什么来“再生” ?
您可以更简单地使用 cat、tr 和 head 来完成此操作。例如:
cat /dev/urandom | tr -dc '0-9a-zA-Z' | head -c100
Run Code Online (Sandbox Code Playgroud)
此管道中的命令将从 stdin 中删除与指定字符集不匹配的任何tr字符。将打印前 100 个字符,然后退出,终止整个命令。head
这将生成一个包含字母数字字符的 100 个字符串。要使其重命名,您只需要使用命令替换:
for file in *.jpg
mv -n ${file} $(cat /dev/urandom | tr -dc '0-9a-zA-Z' | head -c100).jpg
Run Code Online (Sandbox Code Playgroud)
在 zsh 中,for具有单个语句的循环不需要用door包围done。mv标志-n将防止它覆盖现有文件 - 以防万一您对随机字符串感到不走运。
在我的 mac(使用 macOS High Sierra)上,它/dev/urandom给了我二进制字节,所以上面的解决方案导致tr: Illegal byte sequence,所以我曾经base64将字节转换为字符:
cat /dev/urandom | base64 | tr -dc '0-9a-zA-Z' | head -c100
Run Code Online (Sandbox Code Playgroud)
或者我找到了一个没有 base64 的解决方案,这样你也可以得到标点符号:
cat /dev/urandom | LC_ALL=C tr -dc '\''[:alnum:]\!\@\#$\-\.\,'\'' | head -c40
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
管道传输会read导致隐式子 shell,因此我创建了一个显式子 shell 以保证我仍然可以访问该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
Run Code Online (Sandbox Code Playgroud)