今天是个好日子。
我正在尝试将我的音乐提供给 mplayer,就像这样:mplayer *
,但是曲目顺序错误。
以下是我用ls
(以及ls -1
,ls -1 | sort
)得到的结果,请注意音乐会中数字“I”、“II”、“III”的顺序:
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: II.Largo e Spiccato.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: I. Adagio e spiccato.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: II.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: III.Larghetto.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: IV. Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: II.Largo.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: I.Adagio.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: II.Allegro assai.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: II.Largo.mp3
看起来,排序是通过曲目名称而不是曲目编号来执行的,我该如何告诉 bash 按字典顺序对文件进行排序?
以下是一些可能相关的信息:
$ LC_ALL=C type ls
ls is aliased to `ls --color=auto'
$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$ LC_ALL=C bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
$ LC_ALL=C ls --version
ls (GNU coreutils) 8.13
Copyright (C) 2011 Free Software Foundation, Inc.
更新。我将两个文件名存储到文件中:
$ ls -1 | head -n1 > fname1; ls -1 | head -n2 | tail -n1 > fname2
meld
然后用( GUI)检查这两个文件,diff
以确保其中没有不可拆分空格之类的字符,因为这些字符可能会扰乱排序。所以……没有这样的字符,除了明显可见的字符外,没有任何区别。第二个和第三个文件名也是如此。
答案1
您可以在命令执行期间临时设置您的语言环境:我将您的文件列表放在名为的文件中files
:
你看到什么了:
$ LC_ALL='ru_RU.UTF-8' sort files
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: II.Largo e Spiccato.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: I. Adagio e spiccato.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: II.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: III.Larghetto.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: IV. Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: II.Largo.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: I.Adagio.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: II.Allegro assai.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: II.Largo.mp3
按您想要的排序:
$ LC_ALL=C sort files
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: II.Largo e Spiccato.mp3
Antonio Vivaldi - Op.3 concerto No.1 D-dur RV 549: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: I. Adagio e spiccato.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: II.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: III.Larghetto.mp3
Antonio Vivaldi - Op.3 concerto No.2 g-moll RV 578: IV. Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: II.Largo.mp3
Antonio Vivaldi - Op.3 concerto No.3 G-dur RV 310: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: I.Adagio.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: II.Allegro assai.mp3
Antonio Vivaldi - Op.3 concerto No.4 e-moll RV 550: III.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: I.Allegro.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: II.Largo.mp3
Antonio Vivaldi - Op.3 concerto No.5 A-dur RV 519: III.Allegro.mp3
具体来说,您需要将LC_COLLATE
变量设置为C
答案2
由于您已经解决了您的问题(至少对于最多 8 个罗马数字),因此这是一个一般性的评论:
ls *
在将文件传递到音乐播放器时检查文件顺序并不是一个好选择mplayer *
。这是因为ls
它本身可以重新排列文件——并且它绝不保证该机制与 shell 使用的机制相同。这取决于您的设置。改用echo *
-- 或 以获得更漂亮的输出printf "%s\n" *
。
此示例通过我的个人别名说明了这一点ls="ls -v"
:
$ touch 1 2 3 12
$ ls *
1 2 3 12
$ echo *
1 12 2 3
$ printf "%s\n" *
1
12
2
3
使用 可以实现更好的解决方案zsh
,但据我所知 不能使用bash
:
Mikael Magnusson 发布了宏伟的功能处理 zsh 邮件列表中的罗马数字。不深入讨论函数本身的细节,它的工作方式如下:
$ touch I II III IV V VI VII VIII IX X L C D M
$ print *
C D I II III IV IX L M V VI VII VIII X
$ print *(no+romansort)
I II III IV V VI VII VIII IX X L C D M
最后,打印命令(no+romansort)
告诉 shell,你想要对数字进行排序 ( n
) 并使用自定义函数 ( o+
) 首先解析文件名。
当罗马数字只是文件名的一部分时,这当然有效。但请注意,您需要HIST_SUBST_PATTERN
设置该选项!
答案3
由于某种原因,在 Mac OSX (10.8.3) 上排序确实按正确的顺序对罗马数字进行排序。
尽管如此,在进行排序之前,先用罗马数字代替怎么样?
cat filename.txt | sed 's/IV/4/g' | sed s'/III/3/g' | sed 's/II/2/g' | sed 's/I/1/g' | sort
这对我来说是有效的(但我再次在 OSX 上尝试了这个)。