在perl中使用管道对文件进行排序
Sort file using pipe in perl
我正在寻找一种使用管道对文件进行排序的方法。我在网上查了不同的例子,但我还是很困惑
假设我有一个名为 "perlRocks.txt" 的文件,我想对其进行排序。
这是我目前拥有的:
open(SORT, "| sort>perlRocks.txt") or die "Can't sort";
close (SORT);
我错过了什么?
不用管道,用system
代替:
system("sort perlRocks.txt");
这将调用系统命令 sort
并给它 perlRocks.txt
作为参数。您将在调用脚本的 shell 中看到 sort
的输出。
当然,只用这个命令,排序的内容就会显示出来,然后就被忘记了。这可能是也可能不是您的想法。如果您想永久存储排序后的行,您需要将输出重定向到另一个文件。
perl当然自带sort operator, so that you don't have to use an external sort command: sort @lines
. In order to get the content of your file into @lines
, you might want to use the module File::Slurp
:
use warnings;
use strict;
use File::Slurp;
my @lines = read_file('perlRocks.txt');
print sort @lines;
这不是使用 perl 进行排序。要在 perl 中执行此操作,您需要:
open ( my $input_fh, "<", "perlRocks.txt" ) or die $!;
my @lines = <$input_fh>;
print sort @lines;
您正在尝试调用命令 sort
。
您正在打开管道进行写入。如果您已经有了这个文件,您可能希望对阅读内容进行排序。请参阅下面带有 $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);
输出管道有更安全的版本,它避免了 shell 解释 FILE_NAME_OUT 内容的问题(您可以转义此内容,但是...不行。)
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 模块。
我正在寻找一种使用管道对文件进行排序的方法。我在网上查了不同的例子,但我还是很困惑
假设我有一个名为 "perlRocks.txt" 的文件,我想对其进行排序。
这是我目前拥有的:
open(SORT, "| sort>perlRocks.txt") or die "Can't sort";
close (SORT);
我错过了什么?
不用管道,用system
代替:
system("sort perlRocks.txt");
这将调用系统命令 sort
并给它 perlRocks.txt
作为参数。您将在调用脚本的 shell 中看到 sort
的输出。
当然,只用这个命令,排序的内容就会显示出来,然后就被忘记了。这可能是也可能不是您的想法。如果您想永久存储排序后的行,您需要将输出重定向到另一个文件。
perl当然自带sort operator, so that you don't have to use an external sort command: sort @lines
. In order to get the content of your file into @lines
, you might want to use the module File::Slurp
:
use warnings;
use strict;
use File::Slurp;
my @lines = read_file('perlRocks.txt');
print sort @lines;
这不是使用 perl 进行排序。要在 perl 中执行此操作,您需要:
open ( my $input_fh, "<", "perlRocks.txt" ) or die $!;
my @lines = <$input_fh>;
print sort @lines;
您正在尝试调用命令 sort
。
您正在打开管道进行写入。如果您已经有了这个文件,您可能希望对阅读内容进行排序。请参阅下面带有 $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);
输出管道有更安全的版本,它避免了 shell 解释 FILE_NAME_OUT 内容的问题(您可以转义此内容,但是...不行。)
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 模块。