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

5

cat、tr、および head を使用するだけで、これをより簡単に行うことができます。例えば:

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

このパイプラインのコマンドは、指定された文字セットに一致しないtr文字を stdin から削除します。は最初の 100 文字を出力して終了し、コマンド全体を終了します。head

これにより、英数字を含む 100 文字の文字列が生成されます。これを名前変更にするには、コマンド置換を使用するだけです:

for file in *.jpg
    mv -n ${file} $(cat /dev/urandom | tr -dc '0-9a-zA-Z' | head -c100).jpg

zsh では、単一のステートメントを含むループをorforで囲む必要はありません。mv へのフラグは、既存のファイルを上書きするのを防ぎます - ランダムな文字列で本当に不運になった場合に備えて。dodone-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と暗黙的なサブシェルが発生するため、明示的なサブシェルを作成して、引き続き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 に答える