bashを使用してフォルダから重複していないランダムファイルを選択するには?

bashを使用してフォルダから重複していないランダムファイルを選択するには?

このコマンドを使用して任意のファイルを選択できます

find ./ -type f | shuf -n 1

ただし、時には同じファイルが表示されることもあります。
重複したファイルの選択を中止できますか?
これには他のユーティリティがありますか?

再帰サブフォルダがある可能性があるフォルダに約50,000個のtxtファイルがあり、それを見るために任意のファイルを選択したいが、もう一度見たくない。 +毎日新しいファイルがフォルダに追加されます...

ベストアンサー1

コードの問題は、新しいパス名を選択するために毎回リストを再生成することです。リストが作成されたディレクトリに同じファイルを保持する限り、同じパス名を引き続き続けます。

時々スクリプトを実行すると、簡単な答えは次のようになります。プロセスファイルの移動(または削除)。これにより、次回スクリプトを実行してランダムなリストを再生成したときに、処理されたファイルがリストに含まれなくなります。

たとえば、すべてのファイルがディレクトリ内または下にあると仮定すると、$HOME/newfiles次のコマンドはファイルを選択して次に進みます$HOME/oldfiles

myfile=$( find "$HOME/newfiles" -type f -print0 | shuf -z -n 1 )

# use "$myfile" here

# later... move "$myfile" to somewhere else:
mv "$myfile" "$HOME/oldfiles"

この回答の残りの部分では、同じスクリプト呼び出しでランダムなパス名を繰り返す場合について説明します。


ファイルとディレクトリに新しい行が含まれていないと仮定すると、Jeff Schallerが表示されます。コメントにおすすめ:

find ./ -type f | shuf |
while IFS= read -r pathname; do
    # do work with "$pathname"
done

shuf前述のように、階層のパス名に改行文字が含まれていない場合(この場合は名前がめちゃくちゃになる)、これは現在のディレクトリ内または下の一般ファイルへの任意のパス名を提供します。

安全なバリエーションは、nullで終わるリストにリストを混在させることです。

readarray -t -d '' pathnames < <( find . -type f -print0 | shuf -z )
for pathname in "${pathnames[@]}"; do
    # use "$pathname" here
done

この例(および次の例)はhttps://unix.stackexchange.com/a/543188/116858


zshシェルではできます

for pathname in ./**/*(.DNnoe['REPLY=$RANDOM'])
do
   # use $pathname here
done

これは、シェルグロブを使用し、行ベースのテキストフィルタリング機能がないため、ファイル名に改行が問題にならないことを除いて、上記のコードと似ています。リスト) 。

これの良いことは、zsh外部ツールを呼び出す必要がないことです。

おすすめ記事