Perl和Unix如何在相同的序列中对Unicode字符串进行排序和排序?
我试图让Perl和GNU/LinuxSort(1)程序就如何对Unicode字符串进行排序达成一致。我正在用Perl和Unix如何在相同的序列中对Unicode字符串进行排序和排序?,perl,sorting,unix,unicode,locale,Perl,Sorting,Unix,Unicode,Locale,我试图让Perl和GNU/LinuxSort(1)程序就如何对Unicode字符串进行排序达成一致。我正在用LANG=en_US.UTF-8运行排序。在Perl程序中,我尝试了以下方法: 使用$Collator=Unicode::Collate->new() 使用$Collator=Unicode::Collate->new(区域设置=>$ENV{'LANG'}) 它们中的每一个都失败,并出现以下错误(来自Perl端): 输入未排序:[---,]在[($1]之后 输入未排序:[…]位于[
LANG=en_US.UTF-8
运行排序。在Perl程序中,我尝试了以下方法:
- 使用
$Collator=Unicode::Collate->new()代码>
- 使用
$Collator=Unicode::Collate->new(区域设置=>$ENV{'LANG'})代码>
- 输入未排序:[---,]在[($1]之后
- 输入未排序:[…]位于[&]之后
- 输入未排序:[($1]在[1]之后
唯一对我有效的方法是设置排序的
LC_ALL=C
,并在Perl中使用8位字符。但是,这样Unicode字符串的顺序就不正确了。使用Unicode::sort或Unicode::sort::Locale没有任何意义。您不是在尝试基于Unicode定义排序,而是在尝试基于loc排序这就是use locale;
的作用
我不知道为什么您没有从use locale;
下的cmp
中获得所需的顺序
您可以处理解压缩的文件
for q in file1.uniqc file2.uniqc ; do
perl -ne's/^\s*(\d+) //; for $c (1..$1) { print }' "$q"
done | sort | uniq -c
当然,这需要更多的临时存储空间,但你会得到你想要的订单
我发现一个案例
use locale;
没有导致Perl的sort
/cmp
给出与sort
实用程序相同的结果。奇怪
$ export LC_COLLATE=en_US.UTF-8
$ perl -Mlocale -e'print for sort { $a cmp $b } <>' data
(
($1
1
$ perl -MPOSIX=strcoll -e'print for sort { strcoll($a, $b) } <>' data
(
($1
1
$ sort data
(
1
($1
$export LC\u COLLATE=en\u US.UTF-8
$perl-Mlocale-e'print用于排序{$a cmp$b}数据
(
($1
1.
$perl-mpoix=strcoll-e'print for sort{strcoll($a,$b)}数据
(
($1
1.
$sort数据
(
1.
($1
说实话,排序
实用程序很奇怪
在评论中,@ninjalj指出,这种奇怪可能是由于未定义权重的字符造成的。在比较这些字符时,顺序是未定义的,因此不同的引擎可能会产生不同的结果。重新创建精确顺序的最佳方法是通过使用
sort
实用程序,但听起来好像是这样不能保证总是得到相同的顺序。是否正确调用了排序
?Unicode::Collate不会更改排序
的默认行为;您必须使用自定义比较函数。实际的Perl代码(用于8位字符)位于。它设计用于合并多个sort | uniq-c
调用的输出。请注意sort
使用LC\u-COLLATE
,而不是LANG
。另请参见:这是预期的。优先级是LC\u-COLLATE,如果没有定义LC\u-ALL,如果没有定义LANG。请参见我正在对20GB数据集的性能进行基准测试,因此我无法确定我买不起次优的解决方案。您所描述的情况正是我面临的问题类型。请注意,我不太关心将使用的特定区域设置,只要它合理地适用于Unicode字符串(例如DUCET),并且它适用于sort(1)和Perl。Re“我正在测试20GB数据集的性能”“它与sort(1)和Perl的工作原理相同”,这是真的吗?您真的需要使用sort
实用程序吗?Perl不是使用UCA进行排序,而glibc使用iso14651吗?@ninjalj,我认为基于区域设置的排序是由系统文件定义的(我多次听说机器上的区域设置被破坏)