人間が読める形式での数字による拡張

人間が読める形式での数字による拡張

そこで、ファイル名を入力として受け取るコンソール プレーヤーで MP3 を再生したいと思います。次のファイルがあり、シェル (zsh) によって展開されますls -1 **

1 - Main title.mp3
10 - End title.mp3
2 - Intro.mp3 
...

しかし、明らかに、私が実際に望む順序は次のようになります。

1 - Main title.mp3
2 - Intro.mp3 
...
10 - End title.mp3

それを実現するにはどのようなシェル拡張魔法が必要ですか?

巧妙なパイプを使えば同じことができることは分かっていますが、sort -hそれは実際には選択肢ではありません私は怠け者のタイピストだからしたがって、曲を追加するための小さなシェル スクリプトを作成しない限り、nyxmms2 add /path/to/dir/*.mp3zsh の拡張機能内でフィルタリングを行う方法を検討している理由は、むしろそうしたいからです... また、ログ ファイルやリビジョンなど、他の多くの状況にも当てはまるため、これが可能かどうかを知りたいです...

答え1

使用n グロブ修飾子

print -lr -- *.mp3(n)

デフォルトの並び替え順序を変更するには、numeric_glob_sortオプション。

setopt numeric_glob_sort
print -lr -- *.mp3

numeric_glob_sortmay が有効なときに 1 つのパターンに対して辞書式順序が必要な場合は、 nglob 修飾子を否定します。

print -lr -- *(^n)

答え2

1 つの方法は、出力の表示方法を制御するために、lsコマンドを通じて出力を実行することです。sort

人間が読める形式で並べ替える-h(別名)を使用できます。--human-numeric-sort

$ ls | sort -h
1 - Main title.mp3
2 - Main title.mp3
10 - Main title.mp3

編集#1 - OPのコメントへの対応

上記は次のようにエイリアスにラップできます。

$ alias lss="ls | sort -h"

上記のコマンドを実行すると、次のように短縮されます。

$ lss
1 - Main title.mp3
2 - Main title.mp3
10 - Main title.mp3

参考文献

答え3

グロブの並び順は変更できますzshジルの答え) ですが、ls引数はいずれにせよソートされ、デフォルトでは辞書順にソートされます。

lsGNU の場合は、数値順にソートするオプションlsを使用できます。-v

ls -1v

または:

ls -1vd -- *

これは と同等ではありません。sort -hなぜならsort -h、 は の出力のようなものをソートするためのものでdu -hあり、 は1.12Gより大きいからです999M。一方ls -v、 とzsh(n)グロブ修飾子はバージョン番号のようなものをソートするように設計されています (たとえば、1.20 は 1.4 より大きい)。

これらの条件を満たすグロブが必要な場合は、そのための zsh ソート関数を記述する必要があります。

zsh では、関数を使用して glob ソート順序を定義し、それを として使用できます*(o+that-function)。は、変数that-function内でソートするファイル名を受け取り$REPLY、同じ変数に返す必要があります。これにより、辞書式にソートできるようになります(も提供されているzsh場合は数値的にもソートできます)。n

何かのようなもの:

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))}
}

1.1G をすべてその値 (1181116006.4) に置き換えます。

これを次のように使用できます。

ls -1Ud -- *(no+h)

-UGNUlsオプションはls ない引数を並べ替える)。

1.20ただし、小数部分のある数値の場合は、次のように並べ替えられるため、うまく機能しません1.3

$ ls
1.20  1.3  3.1G  500M
$ ls -v1Ud -- *(no+h)
1.3
1.20
500M
3.1G

オプションの接尾辞が付いたあらゆる種類の 10 進浮動小数点数 (-1e20M、1E-20、100k、3000M など) をソートする場合、zsh辞書式または数値的に正の 10 進整数に制限された順序でしかソートできないため、それらを同じ順序で辞書式にソートする文字列、または同じ順序で数値的にソートする正の 10 進整数に変換する関数が必要になります。

zsh利用可能な場合は 64 ビットの数値で浮動小数点演算と 10 進演算を行うので、それらの数値 (または少なくともzsh浮動小数点数でサポートされている範囲) を 0 から 2 63までの整数に変換する浮動小数点関数を適用できます。対数関数を使用することもできます。次のようになります。

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)))))]}
}

用途:

print -rl -- *(no+h)

または、数値ソートにフォールバックして、たとえば 1000000000000000001 と 10000000000000000002 (zsh浮動小数点精度で同じ対数を持つ) を区別するには、次のようにします。

print -rl -- *(noe:h:on)

すると、さらに良いものが得られます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

さて、あなたの特定のnyxmms2の問題については、Gillesの回答を補足するために、あなたが怠け者のタイピストであれば、今度は次のように定義することもできます。選択音楽ファイルに対して、(「順序付け」の代わりに) 次のような機能を使用します。

m() [[ $REPLY == (#i)*.(mp3|ogg)(-.) ]]

nyxmms2 *Zep*(n+m)

または変数を使用します:

m='.(#i)(mp3|ogg)(n-.)'
nyxmms2 *Zep*$~m

またはグローバルエイリアス:

alias -g @m='./*.(#i)(mp3|ogg)(n-.)'
nyxmms2 @m

numericglobsort のみをオンにするにはnyxmms2、次のようにします。

preexec() {[[ $1 = nyxmms2* ]] && setopt numericglobsort}
precmd setopt nonumericglobsort

答え4

これを行うには、常にシェル拡張を使用できます。

nyxmms2 add $(ls /path/to/dir/*.mp3 | sort -n)

音楽を扱っているので、「プレイリスト」を作成するかもしれません

ls /path/to/album/or/song/*.mp3 | sort -n >> /path/to/playlist
nyxmms2 add < /path/to/playlist

関連情報