Ich möchte also einige MP3s in einem Konsolenplayer abspielen, der Dateinamen als Eingaben akzeptiert. Ich habe die folgenden Dateien, die von ls -1 *
where bereitgestellt *
und von meiner Shell (zsh) erweitert werden:
1 - Main title.mp3
10 - End title.mp3
2 - Intro.mp3
...
Ich möchte sie aber eigentlich folgendermaßen angeordnet haben:
1 - Main title.mp3
2 - Intro.mp3
...
10 - End title.mp3
Welche Shell-Erweiterungsmagie benötige ich, um dies zu erreichen?
Ich weiß, dass ich mit ein paar cleveren Rohren dasselbe erreichen könnte, sort -h
aber das ist keine wirkliche Option.weil ich eine faule Schreibkraft bin. Wenn ich also kein kleines Shell-Skript zum Hinzufügen eines Songs geschrieben habe, würde ich lieber nyxmms2 add /path/to/dir/*.mp3
Folgendes tun. Deshalb schaue ich mir an, wie die Filterung innerhalb der zsh-Erweiterung funktioniert ... Außerdem möchte ich wissen, ob dies möglich ist, da es auch auf viele andere Situationen zutrifft – beispielsweise Protokolldateien oder Revisionen oder ...
Antwort1
Verwenden Sie dien
Glob-Qualifizierer.
print -lr -- *.mp3(n)
Sie können die Standardsortierreihenfolge ändern, indem Sie dienumeric_glob_sort
Möglichkeit.
setopt numeric_glob_sort
print -lr -- *.mp3
Wenn Sie eine lexikografische Reihenfolge für ein Muster benötigen, während numeric_glob_sort
möglicherweise wirksam ist, negieren Sie den n
Glob-Qualifizierer.
print -lr -- *(^n)
Antwort2
Ein Ansatz wäre, die Ausgabe ls
über den Befehl auszuführen sort
, um zu steuern, wie die Ausgabe angezeigt wird.
-h
Sie können (auch bekannt als ) verwenden, --human-numeric-sort
das die Dinge in einer für Menschen lesbaren Form sortiert.
$ ls | sort -h
1 - Main title.mp3
2 - Main title.mp3
10 - Main title.mp3
EDIT #1 - Umgang mit dem Kommentar des OP
Das Obige kann wie folgt in einen Alias verpackt werden:
$ alias lss="ls | sort -h"
Das Ausführen des obigen Befehls würde sich dann auf Folgendes reduzieren:
$ lss
1 - Main title.mp3
2 - Main title.mp3
10 - Main title.mp3
Verweise
Antwort3
Sie können die Sortierreihenfolge im zsh
Globbing ändern (sieheGilles' Antwort), ls
sortiert seine Argumente aber trotzdem und standardmäßig lexikografisch.
Wenn es sich bei Ihrem ls
System um GNU handelt ls
, können Sie die -v
Option zum numerischen Sortieren verwenden:
ls -1v
Oder:
ls -1vd -- *
Dies ist nicht dasselbe wie , sort -h
da sort -h
es zum Sortieren von Dingen wie der Ausgabe von dient du -h
, d. h. wo 1.12G
größer ist als 999M
, während die Globbing-Qualifizierer von ls -v
und auf das Sortieren von Dingen wie Versionsnummern ausgerichtet sind (wobei 1,20 beispielsweise größer ist als 1,4).zsh
(n)
Wenn Sie ein Globbing wünschen, das diese Voraussetzungen versteht, müssen Sie dafür eine Zsh-Sortierfunktion schreiben.
Mit zsh können Sie die globale Sortierreihenfolge mit einer Funktion definieren und sie als verwenden *(o+that-function)
. that-function
Übernimmt den zu sortierenden Dateinamen in der $REPLY
Variablen und sollte in dieselbe Variable etwas zurückgeben, das zsh
dann lexikografisch (oder numerisch, wenn n
ebenfalls bereitgestellt) sortiert werden kann.
Etwas wie:
h() {
local -A x
local match
setopt localoptions extendedglob
x=(k 1 K 1 M 2 G 3 T 4 P 5 E 6)
REPLY=${REPLY//(#b)((|[0-9]#.)[0-9]##)([${(kj::)x}])/$((match[1]*2**$x[$match[3]]0))}
}
würde alle 1,1 G durch ihren Wert (1181116006,4) ersetzen.
Die Sie dann verwenden können als:
ls -1Ud -- *(no+h)
( -U
ist die GNU- ls
Option, um zu sagenls
nichtum seine Argumente zu sortieren).
Das funktioniert jedoch nicht so gut bei Zahlen mit Dezimalstellen, da die Sortierung beispielsweise 1.20
nach folgendem Schema erfolgen würde:1.3
$ ls
1.20 1.3 3.1G 500M
$ ls -v1Ud -- *(no+h)
1.3
1.20
500M
3.1G
Für etwas, das alle Arten von dezimalen Gleitkommazahlen mit optionalen Suffixen (wie -1e20M, 1E-20, 100k, 3000M) sortieren würde, weil zsh
die Sortierung lexikografisch oder numerisch nur auf positive Dezimalzahlen beschränkt ist, bräuchten wir eine Funktion, um diese entweder in Zeichenfolgen umzuwandeln, die lexikografisch in der gleichen Reihenfolge sortiert werden, oder in positive Dezimalzahlen, die numerisch in der gleichen Reihenfolge sortiert werden.
zsh
führt Gleitkomma- und Dezimalarithmetik mit 64-Bit-Zahlen durch, sofern verfügbar. Wir könnten also eine Gleitkommafunktion anwenden, die diese Zahlen (oder zumindest den von zsh
Gleitkommazahlen unterstützten Bereich) in eine Ganzzahl von 0 bis 2 63 umwandelt . Die Verwendung der Logarithmusfunktion könnte eine Option sein. So etwas wie:
zmodload zsh/mathfunc
h() {
local -A x
local match v
setopt localoptions extendedglob
x=(k 1 K 1 M 2 G 3 T 4 P 5 E 6 Z 7 Y 8)
REPLY=${REPLY//(#b)([-+]|)(([0-9]#.|)[0-9]##([eE]([-+]|)[0-9]##|))\
([${(kj::)x}]|)/[$(([#10]1e15*(1500+ $match[1](745+log((v=$match[2]\
${${match[2]##*[Ee.]*}:+.}*2.**$x[$match[6]]0)==0?2.48e-324:v)))))]}
}
Zu verwenden als:
print -rl -- *(no+h)
Oder greifen Sie auf die numerische Sortierung zurück, um beispielsweise zwischen 100000000000000001 und 100000000000000002 zu unterscheiden (die denselben Logarithmus mit zsh
Gleitkommagenauigkeit haben):
print -rl -- *(noe:h:on)
Dann bekommen wir etwas noch Besseres als sort -h
:
$ ls | sort -h
-4
-3
+20
a2
b1
b10
b2
1e-20Y
1e3
1.20
1.3
3
20
999
1000 1e9
1000 900M
1001
1024
1k
12k
0.000000001G
$ print -rl -- *(noe:h:on)
-4
-3
0.000000001G
1.20
1.3
3
20
+20
999
1e3
1000 900M
1000 1e9
1001
1k
1024
1e-20Y
12k
a2
b1
b2
b10
Nun zu Ihrem spezifischen nyxmms2-Problem, um Gilles' Antwort zu ergänzen: Wenn Sie ein fauler Schreiber sind, könnten Sie dieses Mal auch einAuswahl(anstelle der „Bestell-“)Funktion für Musikdateien, wie:
m() [[ $REPLY == (#i)*.(mp3|ogg)(-.) ]]
nyxmms2 *Zep*(n+m)
Oder verwenden Sie eine Variable:
m='.(#i)(mp3|ogg)(n-.)'
nyxmms2 *Zep*$~m
Oder ein globaler Alias:
alias -g @m='./*.(#i)(mp3|ogg)(n-.)'
nyxmms2 @m
Um nur NumericGlobsort zu aktivieren nyxmms2
, können Sie Folgendes tun:
preexec() {[[ $1 = nyxmms2* ]] && setopt numericglobsort}
precmd setopt nonumericglobsort
Antwort4
Sie können hierfür jederzeit die Shell-Erweiterung verwenden.
nyxmms2 add $(ls /path/to/dir/*.mp3 | sort -n)
Da Sie mit Musik arbeiten, erstellen Sie möglicherweise „Wiedergabelisten“.
ls /path/to/album/or/song/*.mp3 | sort -n >> /path/to/playlist
nyxmms2 add < /path/to/playlist