Mischen Sie Dateinamenargumente in zsh

Mischen Sie Dateinamenargumente in zsh

Angenommen, die Anwendung kann Dateien nur über Befehlszeilenargumente öffnen. Wie kann ich dazu eine Liste von Dateinamen/Pfaden zufällig anordnen?

Ich dachte, das sollte ziemlich einfach sein, aber anscheinend machen Leerzeichen es komplizierter als es sein sollte.


Ein Beispiel:

a.mp3
b.mp3
mit Leerzeichen.mp3

Wenn ich es versuche, $(ls | shuf)wird das Leerzeichen nicht maskiert, was in etwa Folgendes führt with space.mp3 b.mp3 a.mp3.

Auch die Verwendung der Anführungszeichen-Option -Qhilft nicht, da bei der Befehlsersetzung die Anführungszeichen vermieden werden, was zu folgendem Ergebnis führt:\"with space.mp3\" \"a.mp3\" \"b.mp3\"

Ebenso werden die Escape-Befehle von -bget escaped:with\\ space.mp3 a.mp3 b.mp3

Etwas wie find's -exec <application> {} \+ohne den Befund wäre perfekt ...

Antwort1

lsHier ist eine reine Zsh-Variante, die sowohl Folgendes als auch Folgendes entfernt shuf:

mplayer *.mp3(oe:REPLY=\$RANDOM:)

Der Glob Qualifier oführt eden Code zwischen den beiden Doppelpunkten ( :) aus. Dieser wiederum weist jeder Datei eine pseudozufällige Zahl zu $RANDOM, wodurch eine beliebige Reihenfolge entsteht.

Um den Befehl noch etwas undurchsichtiger zu gestalten, vor allem aber um Tastenanschläge einzusparen, kann man eine Shell-Funktion definieren s:

s() { REPLY=$RANDOM }
mplayer *.mp3(oe:s:)

Oder noch besser: Definieren Sie eine Tastenkombination, beispielsweise CTRL+Rfür den Shuffle-Teil:

bindkey -s '^R' '(oe:REPLY=\\$RANDOM:)^M'

Geben Sie jetzt nur mplayer *.mp3gefolgt von ein CTRL+R. Der (oe:REPLY=\$RANDOM:)Teil wird angehängt und die Befehlszeile sofort ausgeführt ( ^M).

Antwort2

Das brauchst du lsüberhaupt nicht. Versuch es

mplayer "${(f)$(shuf -e *.mp3)}"

Das Problem dabei lsist, dass es häufig einen Alias ​​mit etwas wie verwendet ls --color=alwaysund in diesem Fall unsichtbare Zeichen druckt, die von anderen Programmen nicht richtig erkannt werden ( shufin diesem Beispiel).

Antwort3

Ich glaube, ich habe endlich eine Methode herausgefunden:${(f)"$(ls | shuf)"}

Abbauen:

ls | shuf: Dateien/Verzeichnisse wie erwartet neu ordnen.
"$(...)": Die Anführungszeichen belassen die Ausgabe wie sie ist, einschließlich Zeilenumbrüchen.
${(f)...}: Teilt das Ergebnis der Erweiterung an Zeilenumbrüchen auf, wodurch ein Array der Datei-/Verzeichnisnamen entsteht.


"${(f)$(ls | shuf)}"funktioniert auch, ${(f)$(ls | shuf)}, nicht.

verwandte Informationen