我有一个文件,其值由管道|
car tree alfa young|salt brick|23223|
emilia jack albert| way to go|56566|
我正在尝试按字母顺序对第一列进行排序,并将已排序的文件写出来。
alfa car tree young|salt brick|23223|
albert emilia jack| way to go|56566|
我尝试过: 可以排序第一个数组位置,但不能写出所有文件内容。
$filename = 'test.dat';
open (INPUT,"$filename");
open (OUTPUT,">out.dat");
while (<INPUT>)
{
@array = split('\|');
@arr = split(' ',$array[0]);
$,=" ";
print OUTPUT sort @arr,"\n";
}
close (INPUT);
close (OUTPUT);
对每行中的所有内容进行排序。
$filename = 'test.dat';
open (INPUT,"$filename");
open (OUTPUT,">out.dat");
while (<INPUT>)
{
@arr = split(' ');
$,=" ";
print OUTPUT sort @arr,"\n";
}
close (INPUT);
close (OUTPUT);
答案 0 :(得分:2)
如果您偏离代码中硬编码文件名的想法,您的程序将更加灵活。从STDIN
读取并尽可能写入STDOUT
是一个更好的主意。这就是这段代码的作用。
#!/usr/bin/perl
use strict;
use warnings;
while (<>) {
# Split the record into the first field (the one we want to sort)
# and everything else.
my ($first, $rest) = split /\|/, $_, 2;
# Split the first record into words
my @words = split /\s+/, $first;
# Sort @words and then join the line back together and print it.
print join(' ', sort @words), "|$rest";
}
如果我们将此程序存储在名为reorder
的文件中,我们可以从命令行提示符运行它,如下所示:
$ ./reorder < test.dat > out.dat
我们避免打开任何文件句柄(操作系统为我们做了),如果文件名发生变化,我们就不需要更改程序。
答案 1 :(得分:2)
perl -pe 's/^([^|]+)/@a = sort split ' ', $1; "@a";/e' myfile
答案 2 :(得分:1)
将split
行放入数组后
my @ary = split '\|';
您需要split
第一个元素,sort
列表,join
它回来
my $first = join ' ', sort split ' ', shift @ary;
其中shift
删除(并返回)第一个元素。
然后构建字符串
my $new_string = join '|', $first, @ary;
这可以在没有临时变量的情况下完成。最后两个步骤可以在一个语句中完成,所有这些都在print
语句中完成。
评论
请始终使用use warnings;
和use strict;
使用open
open my $fh, '<', $file or die "Can't open $file: $!";
所以使用词法文件句柄($fh
),而不是bareword(typeglobs,FH
)。
不引用不需要引用的内容 - 甚至可能导致错误!例如,请参阅What's wrong with always quoting (perlfaq4)。感谢Sinan Ünür发表评论。
您也可以使用正则表达式
$line =~ s/(.*?)\|/join(" ", sort split " ", $1).q(|)/e;
这会捕获第一个字段(直到管道),并在其上运行上面的代码,由/e
修饰符提供,这使得替换部分被评估为代码。
我们还需要匹配管道,然后将其放回去。使用lookahead
可以避免这种情况$line =~ s/(.*?)(?=\|)/join(' ', sort split ' ', $1)/e;
仅断言(?=...)
内的模式存在,而不消耗它。
答案 3 :(得分:0)
你的第一段代码非常接近正确。您只输出第一列 - 您需要打印出@array
的内容。如果用排序结果替换@array
的第一个元素,那么你就可以这样写出来。
@array = split('\|');
$array[0] = join(" ",sort split(' ',$array[0]));
print OUTPUT join("|",@array),"\n";