
アプリケーションがコマンドライン引数経由でのみファイルを開くことができると仮定すると、これを実現するためにファイル名/パスのリストをランダム化するにはどうすればよいでしょうか?
これはかなり簡単なはずだと思っていましたが、どうやらスペースのせいで必要以上に複雑になっているようです。
例:
a.mp3
b.mp3
スペースあり.mp3
試してみると、$(ls | shuf)
スペースはエスケープされず、次のような結果になりますwith space.mp3 b.mp3 a.mp3
。
引用符オプションを使用しても、-Q
コマンド置換によって引用符がエスケープされ、次の結果になるため、役に立ちません。\"with space.mp3\" \"a.mp3\" \"b.mp3\"
同様に、 get のエスケープ-b
もエスケープされます。with\\ space.mp3 a.mp3 b.mp3
発見事項のないfind
「's」のようなものが完璧でしょう...-exec <application> {} \+
答え1
以下は、 と を削除した zsh のみのバリエーションls
ですshuf
。
mplayer *.mp3(oe:REPLY=\$RANDOM:)
Glob 修飾子は、両方のコロン ( ) の間にあるコードo
を実行します ( ) 。コードは各ファイルに疑似乱数を割り当て、結果として任意の順序になります。e
:
$RANDOM
コマンドをもう少しわかりにくくするために、主にキーストロークを節約するために、シェル関数を定義できますs
。
s() { REPLY=$RANDOM }
mplayer *.mp3(oe:s:)
CTRL+R
または、さらに良い方法として、シャッフル部分用のキーバインディングを定義します。
bindkey -s '^R' '(oe:REPLY=\\$RANDOM:)^M'
ここで、 のmplayer *.mp3
後に のみ と入力するCTRL+R
と、 の(oe:REPLY=\$RANDOM:)
部分が追加され、コマンド ラインがすぐに実行されます ( ^M
)。
答え2
まったく必要ありませんls
。試してみてください
mplayer "${(f)$(shuf -e *.mp3)}"
の問題はls
、 のような別名が付けられることが多くls --color=always
、その場合、他のプログラム (shuf
この例では ) では正しく認識されない非表示の文字が出力されることです。
答え3
ようやく方法を見つけたと思います:${(f)"$(ls | shuf)"}
壊す:
ls | shuf
: 期待どおりにファイル/ディレクトリをシャッフルします。
"$(...)"
: 引用符は、改行を含む出力をそのまま維持します。
${(f)...}
: 展開の結果を改行で分割し、ファイル/ディレクトリ名の配列を生成します。
"${(f)$(ls | shuf)}"
は同様に動作しますが${(f)$(ls | shuf)}
、は動作しません。