使用perl恢复目录中multiple.txt中的特定行

使用perl恢复目录中multiple.txt中的特定行,perl,Perl,我有一个程序的结果,它给了我一些搜索的结果,给了我2000多个文件的txt档案。我只需要在每个文件中指定一行,这就是我一直在尝试的Perl: opendir(DIR, $dirname) or die "Could not open $dirname\n"; while ($filename = readdir(DIR)) { print "$filename\n"; open ($filename, '<', $filename)or die("Could not open fi

我有一个程序的结果,它给了我一些搜索的结果,给了我2000多个文件的txt档案。我只需要在每个文件中指定一行,这就是我一直在尝试的Perl:

opendir(DIR, $dirname) or die "Could not open $dirname\n";

while ($filename = readdir(DIR)) {
 print "$filename\n";
 open ($filename, '<', $filename)or die("Could not open  file.");
  my $line;
  while( <$filename> ) {
    if( $. == $27 ) { 
    print "$line\n";
    last;
    }
 }
}
closedir(DIR);
opendir(DIR,$dirname)或die“无法打开$dirname\n”;
而($filename=readdir(DIR)){
打印“$filename\n”;

打开($filename,该代码有几个问题:

  • 对目录句柄使用老式的裸字标识符,而不是像文件句柄那样使用自动激活变量

  • 对文件名和文件句柄使用相同的变量是非常奇怪的

  • 在尝试打开文件之前,您不会检查该文件是否为目录或普通文件以外的其他文件

  • 27美元

  • 在打印之前,您从未为该
    $line
    变量分配任何内容

  • 除非
    $directory
    是程序的当前工作目录,否则您将遇到

    如果您计划对readdir中的返回值进行filetest,那么最好在有问题的目录前面加上前缀。否则,因为我们没有在那里加chdir,它可能测试了错误的文件

    (将open替换为filetest)

  • 始终
    使用严格;
    使用警告;


就个人而言,如果您只想打印大量文件的第27行,我会转到
awk
find
(使用其
-exec
测试以避免关于命令行最大长度的潜在错误):

如果您在Windows系统上没有安装标准的unix工具,如那些工具,或者它是一个更大程序的一部分,则采用固定的
perl
方式:

#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
use feature qw/say/;
use File::Spec;

my $directory = shift;
opendir(my $dh, $directory);
while (my $filename = readdir $dh) {
    my $fullname = File::Spec->catfile($directory, $filename); # Construct a full path to the file
    next unless -f $fullname; # Only look at regular files
    open my $fh, "<", $fullname;
    while (my $line = <$fh>) {
        if ($. == 27) {
            say $fullname;
            print $line;
            last;
        }
    }
    close $fh;
}
closedir $dh;
#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
use feature qw/say/;
use File::Spec;

my $directory = shift;
opendir(my $dh, $directory);
while (my $filename = readdir $dh) {
    my $fullname = File::Spec->catfile($directory, $filename); # Construct a full path to the file
    next unless -f $fullname; # Only look at regular files
    open my $fh, "<", $fullname;
    while (my $line = <$fh>) {
        if ($. == 27) {
            say $fullname;
            print $line;
            last;
        }
    }
    close $fh;
}
closedir $dh;
#!/usr/bin/env perl
use strict;
use warnings;
use autodie;
use feature qw/say/;
use Path::Tiny;

my $directory = shift;
my $dir = path $directory;
for my $file ($dir->children) {
    next unless -f $file;
    my @lines = $file->lines({count => 27});
    if (@lines == 27) {
        say $file;
        print $lines[-1];
    }
}