Perl在跨文件循环并将其内容写入输出文件时跳过某些文件

时间:2014-03-05 02:28:24

标签: perl

我遇到了Perl的问题,我希望有人可以帮我弄清楚发生了什么。我在一个名为RawData的目录中有大约130,000个.txt文件,我有一个Perl程序将它们加载到一个数组中,然后遍历这个数组,加载每个.txt文件。为简单起见,假设我有四个文本文件,我正在循环

 File1.txt
 File2.txt
 File3.txt
 File4.txt

每个.txt文件的内容如下所示:

 007 C03XXYY    ZZZZ
 008 A01XXYY    ZZZZ
 009 A02XXYY    ZZZZ

其中X,Y,Z是数字。在下面的简化代码中,程序然后在每个.txt文件中仅提取行007,将XX保存为ID,忽略YY并获取变量数据{{ 1}}我称之为ZZZZ。然后它将所有内容写入文件,并在下面的代码中指定标题:

VarVal

我遇到的问题是,例如 #!/usr/bin/perl use warnings; use strict; open(OUTFILE, "> ../Data/OutputFile.csv") or die $!; opendir(MYDIR,"../RawData")||die $!; my @txtfiles=grep {/\.txt$/} readdir(MYDIR); closedir(MYDIR); print OUTFILE "ID,VarName,VarVal\n"; foreach my $txtfile (@txtfiles){ #Prints to the screen so I can see where I am in the loop. print $txtfile","\n"; open(INFILE, "< ../RawData/$txtfile") or die $!; while(<INFILE>){ if(m{^007 C03(\d{2})(\d+)(\s+)(.+)}){ print OUTFILE "$1,VarName,$4\n" } } } 的内容未显示在File3.txt中。但是,Perl找不到匹配并不是问题,因为我通过删除OutputFile.csv并查看代码打印到终端屏幕的内容来检查是否正在执行if语句。显示出来的确切应该是什么。

此外,如果我只是通过注释掉OUTFILEFile3.txt内容以及执行类似opendir之类的内容来循环运行有问题的文件(closedir)。然后,当我运行代码时,my @textfile = "File3.txt";中显示的唯一数据是OutputFile.csv中的内容。但是当它经历循环时,它将不会显示在File3.txt中。另外,我知道OutputFile.csv正被发送到循环中,因为我可以看到它在File3.txt的屏幕上打印出来。我不知道这里发生了什么。

另一个问题是我认为这不是特定于这个特定文件的东西(可能是这样)但是我不能只对这个文件进行故障排除,因为我有130,000个文件而且我碰巧偶然发现了这个事实这个没有被写入输出文件。因此,可能还有其他文件也没有被编写,即使没有明显的理由它们不应该像print $txtfile","\n";那样。

也许是因为我快速连续执行这么多文件,循环130,000个文件,导致某种I / O问题经常随机失败,将内存中的内容写入输出文件?这是我最好的猜测,但我不知道如何诊断或解决这个问题。

这是一个难以调试的问题,但我希望这里的某些人有一些见解,或者看到类似的问题可以为我提供解决方案。

由于

2 个答案:

答案 0 :(得分:1)

我可以在你的代码中看到任何明显的错误。使用autodie有点过时,词法文件句柄会更好。

但是,我建议你通过在第一个值之后使间距变量长度并使最后一个变量可选为0长度来使你的正则表达式稍微限制一些。我也输出文件名。然后您可以看到哪些其他文件由于某种原因未被捕获:

if (m{^007\s+C03(\d{2})\d+\s+(.*)}){
    print OUTFILE "$txtfile $1,VarName,$2\n";
    last;
}

最后,假设每个文件中只有一个007 C03,您可以在找到一个last之后进行调用。

答案 1 :(得分:1)

您可能想尝试对@txtfiles列表进行排序,然后尝试系统地查看输出以查看是否存在。对于随机顺序的130k文件,很难确定你错过了一个。 Perl应该按照它们在目录中出现的实际顺序为您提供文件,这与用户级命令(如ls)不同,因此它可能与您期望的不同。