我正在寻找一种使用管道对文件进行排序的方法。我在网上查了不同的例子,但我仍然感到困惑
假设我有一个名为“perlRocks.txt”的文件,其中包含我想要排序的不同名称。
这是我到目前为止所做的:
open(SORT, "| sort>perlRocks.txt") or die "Can't sort";
close (SORT);
我错过了什么?
答案 0 :(得分:1)
无需使用管道,请改用system
:
system("sort perlRocks.txt");
这将调用系统命令sort
并将其作为参数perlRocks.txt
。您将在调用脚本的shell中看到sort
的输出。
当然,仅使用此命令,将显示已排序的内容,然后将其忘记。这可能是也可能不是你的想法。如果要永久存储已排序的行,则需要将输出重定向到另一个文件。
当然,perl附带了自己的sort运算符,因此您不必使用外部排序命令:sort @lines
。要将文件内容添加到@lines
,您可能需要使用模块File::Slurp
:
use warnings;
use strict;
use File::Slurp;
my @lines = read_file('perlRocks.txt');
print sort @lines;
答案 1 :(得分:1)
这不是使用perl进行排序。要在perl中执行此操作,您需要:
open ( my $input_fh, "<", "perlRocks.txt" ) or die $!;
my @lines = <$input_fh>;
print sort @lines;
您正在尝试调用命令sort
。
答案 2 :(得分:0)
你正在打开写作的管道。如果您已有此文件,则可能需要对已读取的内容进行排序。请参阅下面的$in
示例。如果您想从脚本中写一些内容,请参阅下面的$out
示例。有关更多变体,请参阅open
文档。要对现有文件进行排序,您必须写入新文件然后重命名。最好使用一些shell来完成这项任务。
use strict;
use warnings;
use autodie;
use constant FILE_NAME_IN => 'perlRocks.in';
use constant FILE_NAME_OUT => 'perlRocks.out';
open my $in, '-|', 'sort', FILE_NAME_IN;
while (<$in>) {print};
open my $out, '|-', "sort >'@{[FILE_NAME_OUT]}'";
print $out $_, "\n" for qw(foo bar baz quux);
输出管道有更安全的版本,可以避免FILE_NAME_OUT内容的shell解释问题(你可以转义这个内容,但是......不。)
open my $out, '|-' or do {
close STDOUT;
open STDOUT, '>', FILE_NAME_OUT;
exec 'sort' or die $!;
};
如果你坚持不想使用shell,你可以使用Perl。
use strict;
use warnings;
use autodie;
use constant FILE_NAME_IN => 'perlRocks.txt';
use constant FILE_NAME_OUT => 'perlRocks.txt';
# don't bother with fork if you don't want continue with Perl process
my $pid = fork;
die "cannot fork" unless defined $pid;
unless ($pid) { # use just this code inside in this case
close STDIN;
close STDOUT;
open STDIN, '<', FILE_NAME_IN;
unlink FILE_NAME_IN if FILE_NAME_IN eq FILE_NAME_OUT;
open STDOUT, '>', FILE_NAME_OUT;
exec 'sort' or die $!;
}
waitpid( $pid, 0 );
注意FILE_NAME_IN
和FILE_NAME_OUT
可以相同,但无论如何都不是就地排序。在某些时候,光盘上有两个版本的文件,即使有一个版本可以被隐藏和无法访问。这类任务还有很好的IPC::Run模块。