
ターミナル経由でランダムに選択されたファイルを開きたいのですが、 を見つけました。shuf
これはまさに必要なユーティリティのようですが、使用しているコマンドを再帰的に実行する方法を見つけることができません。
最初は を使用しましたがopen $(ls | gshuf -n1)
、これはフラットなディレクトリ構造がある場合にうまく機能します。これを任意の数のサブディレクトリに再帰させ、 や フォルダーなどのファイルを除外するにはどうすればよいでしょうか.DS_Store
?
答え1
適切なツールは ですfind
。これは再帰的に動作し、主な問題を解決します。方法がわかれば、さまざまなパターンを除外できます。
基本的な使用方法は次のようになります。
open "$(find . -type f | shuf -n1)"
ファイル名に改行があると、このエラーが発生します。ツールによっては、NUL で終了するデータを渡す非 POSIX オプションをサポートしていない場合があります。このスニペットは、私の Debian では動作します:
find . -type f -print0 | shuf -z -n1
ただし、 に埋め込むと$(…)
、末尾の改行 (ある場合) は削除されます。
名前を除外するには、のような構文を使用できます! -name .DS_Store
が、サブディレクトリ全体を除外するには、-prune
落とし穴があります:
- オペランドの順序は重要です。たとえば、
-prune
ディレクトリの場合は の前に-type f
、-print
/ は-print0
通常最後に配置します。 - 論理和 (
-o
)括弧が必要になることが多いそして、それはあなたが望むほど直感的ではありません。 -print
/ を省略すると、-print0
予想以上の結果が返される可能性があります。複雑なロジックの場合は、-print
/ を明示的に含めることをお勧めします-print0
。
さらに詳しく知るには勉強してくださいman 1 find
。これは、2 つのディレクトリと 2 つの名前パターンを除外する実際の例です。
find . \( -name dir1 -o -name "dir 2" \) -prune -o -type f ! \( -name "*.txt" -o -name "echo*" \) -print
適切に引用符で囲む必要があるので$(…)
、内部の引用符は別々に解析されることを知っておく必要があります$(…)
。たとえば、これは適切に引用符で囲まれています:
open "$(find . -type f ! -name "not this file" | shuf -n1)"
(比較するこの答え、癖2)。