Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File 打开目录并在文件中搜索模式_File_Perl - Fatal编程技术网

File 打开目录并在文件中搜索模式

File 打开目录并在文件中搜索模式,file,perl,File,Perl,我的Perl脚本应该打开目录中的所有文件,搜索其中的模式,并打印包含该模式的整行。 下面是代码。代码无法打开该文件 my $dir = 'dir1/dir2'; opendir (DIR, $dir) or die $!; my @dir = readdir DIR; foreach my $item (@dir) { open(FILE, "<", "file.txt") or die "Can't open < file

我的Perl脚本应该打开目录中的所有文件,搜索其中的模式,并打印包含该模式的整行。 下面是代码。代码无法打开该文件

  my $dir = 'dir1/dir2';
    opendir (DIR, $dir) or die $!;
    my @dir = readdir DIR;
    foreach my $item (@dir) {
        open(FILE, "<", "file.txt")
        or die "Can't open < file.txt: $!";
        while($line= <FILE>) {
        print "$line" if $line=~ /pattern/;
    }
    close FILE;
    }
    closedir DIR;
请建议一些方法使其工作。

返回的只是名称file.txt,而不是路径而不是dir1/dir2/path.txt

因此,当程序试图打开$item†时,结果证明没有这样的事情-需要打开$dir/$item。或者,在文件列表中的每个条目前加上前缀,然后使用正确的路径

use warnings;
use strict;

my $dir = 'dir1/dir2';

opendir (my $dh, $dir) or die $!;
my @entries = map { "$dir/$_" } readdir $dh;
closedir $dh;

foreach my $item (@entries) {
    next if not -f $item;
    open(my $fh, "<", $item) or die "Can't open < $item: $!";

    while(my $line = <$fh>) {
        print $line if $line =~ /pattern/;
    }
    close $fh;
}
但是,如果您确实要提前获取整个文件列表,而不是一次读取和处理一个项目,那么您最好立即根据需要对其进行过滤,因此

my @files = grep { -f } glob $dir;
您现在只有常规文件

当然,整个列表也可以在上面的程序中过滤。可以在地图上自己做

在这里,map还通过一个小技巧起到了过滤器的作用:当条目不是普通文件时返回的空列表在返回的列表中变平,从而有效地消失,因此在这种情况下等于不返回任何内容。或者,像往常一样将grep链接到map

这确实使列表又一次被忽略了,但这是优化的,而且几乎不会成为一个问题,除非我们有巨大的文件列表——这本身就带来了问题——而且我们经常这样做

我还想提到的是,也有一些很好的模块

举个例子

这是一个懒惰的迭代器。有关本模块提供的许多其他内容,请参阅文档等

†返回的不是file.txt,而是名称file.txt,而不是路径dir1/dir2/path.txt

因此,当程序试图打开$item†时,结果证明没有这样的事情-需要打开$dir/$item。或者,在文件列表中的每个条目前加上前缀,然后使用正确的路径

use warnings;
use strict;

my $dir = 'dir1/dir2';

opendir (my $dh, $dir) or die $!;
my @entries = map { "$dir/$_" } readdir $dh;
closedir $dh;

foreach my $item (@entries) {
    next if not -f $item;
    open(my $fh, "<", $item) or die "Can't open < $item: $!";

    while(my $line = <$fh>) {
        print $line if $line =~ /pattern/;
    }
    close $fh;
}
但是,如果您确实要提前获取整个文件列表,而不是一次读取和处理一个项目,那么您最好立即根据需要对其进行过滤,因此

my @files = grep { -f } glob $dir;
您现在只有常规文件

当然,整个列表也可以在上面的程序中过滤。可以在地图上自己做

在这里,map还通过一个小技巧起到了过滤器的作用:当条目不是普通文件时返回的空列表在返回的列表中变平,从而有效地消失,因此在这种情况下等于不返回任何内容。或者,像往常一样将grep链接到map

这确实使列表又一次被忽略了,但这是优化的,而且几乎不会成为一个问题,除非我们有巨大的文件列表——这本身就带来了问题——而且我们经常这样做

我还想提到的是,也有一些很好的模块

举个例子

这是一个懒惰的迭代器。有关本模块提供的许多其他内容,请参阅文档等


†而不是该文件.txt

只返回名称,而不是路径。因此,当您尝试打开file.txt时,没有这样的事情-您需要说$dir/file.txt。另一种方法是在整个列表前面加上前缀,因此my@dir=map{$dir/$\uj}readdir-dir;现在@dir中的文件具有正确的路径hmm,如果按照您的逻辑,您尝试读取每个dir中的file.txt,但不是目录中的每个文件。您的描述与代码的逻辑不匹配。我不确定perl脚本是否是解决任务的强制要求。否则,您可以使用find和grep获得相同的结果find/some/dir-exec grep[pattern]{}-ls。此命令将搜索目录和子目录中的每个文件。@PolarBear也可以这样做,但不需要查找,因为grep有方法指定要搜索的内容,这里它很简单,grep[options]模式dir1/dir2/*其中选项将决定如何显示查找只需注意:并非所有版本的grep都支持子目录中的递归搜索-find/grep工作了很长时间,从未失败过。返回的只是名称,而不是路径。因此,当您尝试打开file.txt时,没有这样的事情-您需要说$dir/file.txt。另一种方法是在整个列表前面加上前缀,因此my@dir=map{$dir/$\uj}readdir-dir;现在@dir中的文件具有正确的路径hmm,如果按照您的逻辑,您尝试读取每个dir中的file.txt,但不是目录中的每个文件。您的描述与代码的逻辑不匹配。我不确定perl脚本是否是解决任务的强制要求。否则,您可以使用find和grep获得相同的结果find/some/dir-exec grep[pattern]{}-ls。此命令将搜索目录和子目录中的每个文件。@PolarBear也可以这样做,但不需要查找,因为grep有方法指定要搜索的内容,这里它很简单,grep[options]模式dir1/dir2/*其中选项将决定如何显示查找只需注意:并非所有版本的grep都支持subdir中的递归搜索 ectories-find/grep工作了很长时间,从未失败过。
my @files = grep { -f } map { "$dir/$_" } readdir $dh;
use Path::Tiny;

my $it = path($dir)->iterator;

while (my $entry = $it->()) { 
    # it omits . and ..
}