Erweiterung mit Zahlen in menschenlesbarem Format

Erweiterung mit Zahlen in menschenlesbarem Format

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 -haber 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/*.mp3Folgendes 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_sortMöglichkeit.

setopt numeric_glob_sort
print -lr -- *.mp3

Wenn Sie eine lexikografische Reihenfolge für ein Muster benötigen, während numeric_glob_sortmöglicherweise wirksam ist, negieren Sie den nGlob-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.

-hSie können (auch bekannt als ) verwenden, --human-numeric-sortdas 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 zshGlobbing ändern (sieheGilles' Antwort), lssortiert seine Argumente aber trotzdem und standardmäßig lexikografisch.

Wenn es sich bei Ihrem lsSystem um GNU handelt ls, können Sie die -vOption zum numerischen Sortieren verwenden:

ls -1v

Oder:

ls -1vd -- *

Dies ist nicht dasselbe wie , sort -hda sort -hes zum Sortieren von Dingen wie der Ausgabe von dient du -h, d. h. wo 1.12Ggrößer ist als 999M, während die Globbing-Qualifizierer von ls -vund 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 $REPLYVariablen und sollte in dieselbe Variable etwas zurückgeben, das zshdann lexikografisch (oder numerisch, wenn nebenfalls 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)

( -Uist die GNU- lsOption, um zu sagenls nichtum seine Argumente zu sortieren).

Das funktioniert jedoch nicht so gut bei Zahlen mit Dezimalstellen, da die Sortierung beispielsweise 1.20nach 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 zshdie 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.

zshfü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 zshGleitkommazahlen 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 zshGleitkommagenauigkeit 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

verwandte Informationen