PERL:从A到Z排序字母



我正在尝试从a到Z排序文件中的字母例如:a a B d r g排序:A A B d g r

@ARGV == 2 or die "Usage: $0 infile outfilen";
open $old,  '<', $ARGV[0] or die $!;
open $new, '>', $ARGV[1] or die $!;
@mass=<$old>;
@array=qw(@mass);
@sort=sort @array;
@mass1=sort {uc $a cmp uc $b} @sort;
print $new @mass1;

我哪里错了?

我认为您不了解标准文本排序是基于ascii的。因为所有的大写字母都是小写的,所以输入也是如此。因此,你直接订购的sort就是( 'A', 'B', 'a', 'd', 'g', 'r' )

double比较两个字符串。在本例中,您将需要传递一个例程来排序。

@sort= sort { lc $a cmp lc $b or $a cmp $b } @array;

我不确定你打算用qw做什么,但是足以说明@mass的内容将永远不会被使用。

@array = qw(hello world);

将导致@array被定义为包含2个字符串helloworld。它是

的简写
@array = ('hello', 'world');

这就是为什么

@array=qw(@mass);

计算结果为('@mass') -一个包含5个字符的字符串@mass的数组。

也许这就是你做错的地方。如果你尝试

@array = map { split /s+/} @mass;

@mass是行列表。每一行都有单词或字母,用空格分隔。最后一行所做的是将每一行映射为split /s+/ -这将拆分每一行将'ba ab a G'这样的行放入列表,如('ba', 'ab', 'a', 'G')@array变成一个单词/字母列表

那么问题就在于你想如何排序了。请看另一个答案

哦,记得写文件的时候把空格放回去:

print $new (join " ", @mass1);

如果你想让每一行相互依赖地排序,这也很容易:

$mass1 = join "n", map { join " ", sort (split /s+/) }  @mass

读,'对于@mass中的每一行,在空间上分割,排序并再次与空间连接',并使用生成的数组,与newline连接以产生文件的输出。

请注意,您可以将sortsort { $a cmp $b }等比较器放在一起。

如果你的文件太大,那么循环可能是谨慎的:

for my $mass (<$old>) {
    my $sorted_line = join " ", sort (split /s+/, $mass);
    print $new "$sorted_linen";
}

您需要找到要使用的正确LOCALE,以便所有函数(sort等)使用的顺序都使用正确的LOCALE并据此进行排序。

请参阅这个页面,其中显示了大多数定义区域设置的变量,并查找LANG和LC_ALL。和LC_COLLATE(我不得不承认,我不太确定在什么时候使用哪个)。LC_ALL应该优先于其他的,所以你可以改变它来设置所有的LC_*值…请测试,ymmv)

我相信您可能需要使用unicode区域设置之一。Ascii不会做你想要的,因为在Ascii中,大写字母在常规字母之前。

查找可以使用的语言环境:locale -a

查看当前设置的区域设置:locale(用户和系统范围的值是可能的)

你可能需要一些包含"utf-8"的东西来获得你寻找的顺序

Then:(例如en_US。UTF-8可用):

在排序中使用它之前,定义要使用的区域设置:

LC_ALL=en_US.UTF-8

(或您需要设置的任何值,如"locale -a"所示)

(如果需要,保存/恢复调用前后的值)

在shell中,您可能最好将"export"添加到您重新定义的变量中,以确保子shell也使用新值(例如:something | sort:在bash中,sort将在子shell中,因此使用默认值LC_*,或者使用导出值,如果您导出了它!)

相关内容

  • 没有找到相关文章

最新更新