タイトルからわかるように、私はbashで次のことを行うプログラムを書くのが好きです。
ディレクトリ内のすべてのファイルを繰り返します(各ディレクトリには100個のファイルがあります)。
1から100までの未割り当て乱数を割り当てます。
ファイル名をX(割り当てられた乱数)ファイル名の形式で別のファイル(results.txt)に保存します。
ファイル名を任意の数字に変更
ファイルを繰り返す方法を知っていますが、残りの部分は私の能力を少し超えています。この問題に対するあなたの助けに非常に感謝します:)
ベストアンサー1
この練習の最大の難点は、100個のファイルのそれぞれに固有の乱数を生成することです。この問題に対する解決策は、必要な数字(1〜100)を生成し、数字とファイル名を関連付ける前に数字を混在させる(またはファイル名のリストを混在させる)ことです。最後にやりたいことは、100面サイコロを転がしてすでにその数字を転がしていることを確認し、そうであれば、以前に転がっていない数字が出るまでサイコロを振り直すことです。ファイル数が多い場合は、プロセスが必要になる場合があります。非常に長い時間。 (興味深いことに、私たちはこれを数年前にインタビューの質問として使用しました。)
ファイル名に改行文字が含まれていないとします。
paste <( printf '%d\n' {1..100} ) <( printf '%s\n' dir/* | sort -R ) >result.txt
これにより、ユーティリティを使用してタブで区切られた2つの列が作成されますpaste
。最初の列には、1から100までの整数が順番に含まれます。 2番目の列には、ディレクトリ内の100個のファイルの名前dir
(ディレクトリ名を含む)が含まれています。名前のリストはランダムな順序で並べ替えられます(-R
オプションsort
は標準ではありませんが、通常は利用可能です)。
整数を混在させる代わりにファイル名を並べ替えることもできます。
paste <( printf '%d\n' {1..100} | sort -R ) <( printf '%s\n' dir/* ) >result.txt
ファイル名を変更するには、result.txt
ファイルを読んでください。
while IFS= read -r stuff; do
number=${stuff%%$'\t'*} # the thing before the first tab
pathname=${stuff#*$'\t'} # the thing after the first tab
mv -i -- "$pathname" "$(dirname -- "$pathname")/$number"
done <result.txt
現在のディレクトリのすべてのサブディレクトリに対してこのコマンドを実行します(このコマンドを実行する前に2回考えて、重要なデータのバックアップを常に維持してください)。
for dirpath in */; do
paste <( printf '%d\n' {1..100} | sort -R ) <( printf '%s\n' "$dirpath"/* )
done >result.txt
while IFS= read -r stuff; do
number=${stuff%%$'\t'*}
pathname=${stuff#*$'\t'}
mv -i -- "$pathname" "$(dirname -- "$pathname")/$number"
done <result.txt
あるいはもう少し簡単に言えば、
for dirpath in */; do
paste <( printf '%d\n' {1..100} | sort -R ) <( printf '%s\n' "$dirpath"/* )
done |
tee result.txt |
while IFS= read -r stuff; do
number=${stuff%%$'\t'*}
pathname=${stuff#*$'\t'}
mv -i -- "$pathname" "$(dirname -- "$pathname")/$number"
done