使用perl恢复目录中多个.txt中的某一行。

问题描述 投票:0回答:1

我有一个程序的结果,它给了我一些搜索的结果,给了我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);

但是第5行的$filename有问题,我不知道有什么办法可以替代它,这样我就不用手动命名每个文件了。

先谢谢你。

perl
1个回答
1
投票

这段代码有几个问题。

  • 用一个老式的裸词标识符来表示目录句柄 而不是像你一样用一个自动变量来表示文件句柄。

  • 在文件名和文件句柄上使用同一个变量是非常奇怪的。

  • 在尝试打开文件之前,你没有检查该文件是一个目录还是其他什么东西,而不是一个普通的文件。

  • $27?

  • 你从来没有给那个 $line 变量在打印前。

  • 除非 $directory 是你的程序的当前工作目录,你遇到了一个在 readdir 文件

    如果你打算从一个readdir中对返回值进行文件测试,你最好把相关的目录前缀。否则,因为我们没有把chdir放在那里,就会测试错误的文件。

    (用open代替filetest)

  • 总是 use strict;use warnings;.


就个人而言,如果你只是想打印大量文件的第27行,我会使用 awkfind (利用其 -exec 测试,以避免潜在的关于命令行最大长度被击中的错误)。)

find directory/ -maxdepth 1 -type -f -exec awk 'FNR == 27 { print FILENAME; print }' \{\} \+

如果你在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;

你也可以考虑使用 glob 来获取文件名,而不是 opendirreaddirclosedir.

如果你有 Path::Tiny 可用,一个更简单的版本是。

#!/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];
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.