使用Perl将文件读入数组

ale*_*lex 14 arrays perl file-io

我目前正在读取一个文件并将数据存储在一个名为的数组中@lines.然后,我使用循环遍历此数组,for并在循环内我匹配某些值:

$find = "fever";

if ($_ =~ /$find/) {
    print "$_\n";
    $number++;
    #@lines =
    #print ("there are : " . $number);
}
Run Code Online (Sandbox Code Playgroud)

目前,我使用的是标量,$find与的价值fever,而不是执行每个过滤重复的语句.

我可以传递数组进行比较而不是标量关键字吗?

Ed *_*ess 33

如果您将文件读入列表,则会立即执行所有操作

@array = <$fh>;  # Reads all lines into array
Run Code Online (Sandbox Code Playgroud)

将其与读入标量上下文进行对比

$singleLine = <$fh>;  # Reads just one line
Run Code Online (Sandbox Code Playgroud)

一次读取整个文件可能是一个问题,但你明白了.

然后你可以grep用来过滤你的数组.

@filteredArray = grep /fever/, @array;
Run Code Online (Sandbox Code Playgroud)

然后你可以使用得到过滤行的计数scalar,这会强制解释数组的标量(即单值)上下文,在这种情况下返回一个计数.

print scalar @filteredArray;
Run Code Online (Sandbox Code Playgroud)

把它们放在一起......

C:\temp>cat test.pl
use strict; use warnings;  # always

my @a=<DATA>;  # Read all lines from __DATA__

my @f = grep /fever/, @a;  # Get just the fevered lines

print "Filtered lines = ", scalar @f;  # Print how many filtered lines we got

__DATA__
abc
fevered
frier
forever
111fever111
abc

C:\temp>test.pl
Filtered lines = 2
C:\temp>
Run Code Online (Sandbox Code Playgroud)

  • 如果它澄清了如何获取任意文件的文件句柄,比如你在`$ filename`中有一个文件名,这将是一个更好的答案.顺便说一句,__DATA__对我来说是新的,但我从来不只是一个偶然的Perl用户. (3认同)

Eug*_*ash 5

如果你有Perl 5.10或更高版本,你可以使用智能匹配(~~):

my @patterns = (qr/foo/, qr/bar/);

if ($line ~~ @patterns) {
    print "matched\n";  
}
Run Code Online (Sandbox Code Playgroud)


Geo*_*Geo 5

使用Tie :: File.它将文件加载到一个数组中,您可以使用数组操作进行操作.解开文件后,其组件将保存回文件中.


Lum*_*umi 5

您也可以使用该File::Slurp模块,这很方便。

use strict;
use warnings;
use File::Slurp 'read_file';

my $fname = shift or die 'filename!';
my @lines = grep /fever/, read_file $fname; # grep with regular expression
print @lines;
Run Code Online (Sandbox Code Playgroud)

如果您是 Perl 新手,请查看mapgrep运算符,它们对于处理列表非常方便。

另外,看看该ack实用程序,它是find/的一个很好的替代品grep。(实际上,这是一个更好的选择。)