【问题标题】:Perl: Manipulating while(<>) loop in file readingPerl:在文件读取中操作 while(<>) 循环
【发布时间】:2016-01-05 08:40:15
【问题描述】:

我的问题是关于从文件中读取行的 while 循环。情况是当while循环while(&lt;FILEHANDLE&gt;)在当前行($_)上执行操作时,我想存储下一行或整个下一行的值。那么解决这个问题的方法是什么?是否有特定的功能或模块来做这件事?

【问题讨论】:

  • 嗯,我从这项任务中学到了很多...只是有另一个小疑问,不想为这么简单的事情打开另一个线程:我有一个空数组@arr 我正在填充通过 for 循环将另一个数组中的元素一个接一个: for ($i=1...scalar@arr2) { push(@arr1,$elements[$i]); } ....它的行为不像预期的那样!谁能建议我我做错了什么? [没有通过谷歌搜索找到特定的解决方案:(]

标签: perl


【解决方案1】:

如果你想一次处理四行并且每行由@FCC分隔,那么你需要改变perl的输入文件分隔符。

在你的脚本里放

$/="\@FCC"

这意味着当您执行 () 时,您在 $_ 中获得的每条记录现在都是文件的四行。

use warnings;
use strict;
local $/="\@FCC";

while (<>) {
    chomp;
    #Each time we iterate, $_ is now all four lines of each record.
}

编辑 您需要反斜杠 @

【讨论】:

  • okei 这很优雅....这个让我忽略了,看起来很有帮助!!!谢谢楼主……
  • @FCC实际上不是数组时在双引号内使用会导致编译错误。
  • 已编辑 - 转义了 @
【解决方案2】:

您可以在任何地方阅读&lt;&gt;,而不仅仅是在循环的开头,例如

while (my $line = <>) {
    chomp $line;
    my $another_line = <>;
    chomp $another_line;
    print "$line followed by $another_line\n";
}

【讨论】:

  • 谢谢你的时间……我知道你说的但那不完全是我要求的……让我解释一下……有四行 L1:@CCF。 ... L2:---characters--- L3:+ L4:---characters--- ,现在我像这样捕获L1: if(/^\@CCF/){ $first_line=$_; $second_line=(这是我想一次性处理相应的第二行的地方,比如 $_+1)}....在 grep 中,您使用 -A 选项处理模式匹配行之后的行,类似的东西!!!
【解决方案3】:

假设您的文件很小(可能小于 1gb),您可以将其填充到一个数组中并遍历它:

use warnings;
use strict;

my @lines;
while (<>) {
    chomp;
    push @lines, $_;
}

my $num_lines = @lines; #use of array in scalar context give length of array                                             
# don't do last line (there is no next one)                                                                              

$num_lines -= 1;

foreach (my $i = 0; $i < $num_lines; $i++) {
    my $next_line = $i+1;
    print "line $i plus $next_line:",$lines[$i],$lines[$i+1],"\n";
}

请注意,我的解决方案的语义与上面的答案有点不同。我的解决方案将打印除第一行之外的所有内容两次;如果您希望所有内容都打印一次,上述解决方案可能更有意义。

【讨论】:

  • 谢谢Doggerel....不,我的文件不小...大于1.5GB并且有超过1000万行:) .....我知道这种方式!!
  • 1.5gb 在现代计算机内存中并没有那么大。如果你有一台 8gb+ram 的机器,我怀疑你会有问题。 4GB 的机器可能工作也可能不工作。
  • 您的用例能否简化为“我需要以 N 行的块处理文件”?如果是这样,行号魔法 var $.应该能帮到你。
  • 不,先生...实际上并不是那么简单...事实上,请解释一下...我有百万行的文件,但是该文件的条目是一组 4 行,即条目=行数/ 4 ....我正在尝试处理这些条目中的每一个,但是从程序上讲,我处理4行的集合...。这4行的起始行始终以@FCC开头。 ..因此当我的 while() 位于第一行 ($_) 时,我需要访问以下 3 行 ....
【解决方案4】:

如果您想从文件中一次读取 n 行,您可以使用 Tie::File 并使用数组一次引用 n 元素,如下所示:

use strict;
use warnings;

use Tie::File;

my $filename = 'path_to_your_file';
tie my @array, 'Tie::File', $filename or die 'Unable to open file';

my $index = 0;
my $size = @array;

while (1) {
    last if ($index > $size); # Be careful! Try to do a better check than this!
    print @array[$index..$index+3];
    print "----\n";
    $index += 4;
}

(这只是一个例子,尝试编写更好的代码)

正如文档所说,文件不会一次全部加载到内存中,因此即使是大文件也可以工作。

【讨论】:

  • 我就知道...有这样的东西!!!!这看起来很有帮助,让我们看看.....和 ​​thaaaaank 你 ChatterOne
猜你喜欢
  • 1970-01-01
  • 2018-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-05
  • 2022-01-21
  • 2012-01-24
  • 1970-01-01
相关资源
最近更新 更多