4

我正在尝试使用以下代码生成一个随机字符串:

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

这部分脚本从包含大量 jpeg 文件的目录中运行,并且应该随机化它们的文件名。问题是$RANDOM变量在迭代期间不会更新,因此每次都给出相同的哈希值。我尝试使用/dev/urandom,它可以工作,但比$RANDOM. $RANDOM每次阅读时我该怎么做才能“重新生成” ?

4

3 回答 3

7

在我的 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
于 2018-01-05T10:22:20.420 回答
5

只需使用 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

在 zshfor中,带有单个语句的循环不需要用door包围done。mv的-n标志将防止它覆盖现有文件 - 以防万一你对随机字符串真的很不走运。

于 2013-10-30T14:20:48.870 回答
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参数。另外,不要解析 ls

顺便说一句,你确定你不只是想要base64输出吗?到目前为止,它比 sha256sum 便宜,我看不出你从 sha256sum 中得到了什么。另外,它会使代码更易于阅读:

for pic in *.jpg; do
  mv "$pic" "$(base64 </dev/urandom | tr -dc 'a-zA-Z0-9' | head -c20).jpg"
done
于 2013-10-24T04:08:00.697 回答