【问题标题】:print doesn't work while iterations are going inside foreach loop迭代在 foreach 循环内进行时打印不起作用
【发布时间】:2016-11-15 11:41:35
【问题描述】:

我试图找到一种在解析日志文件时在命令行上打印进度条的方法。获取日志文件=> foreach 文件 => foreach 行 {do}。

想法:我想在每个“foreach 文件”循环中打印进度条的一部分。含义:如果您只解析 1 个文件,则打印整个栏。当您解析 2 个文件时,为每个文件打印一半的栏,依此类推。您可以在底部找到具体代码。

问题:在所有 foreach 迭代完成后打印输出(打印“*”) - 而不是介于两者之间。详细信息在代码中。

有人知道如何在 foreach 中打印吗?或者可以告诉我问题吗?我不明白:(。

my @logfiles=glob($logpath);

print "<------------------>\n";
$vari=20/(scalar @logfiles);

foreach my $logfile (@logfiles){
    open(LOGFILEhandle, $logfile);
    @lines = <LOGFILEhandle>;

    print "*" x $vari;   #won't work, only after loop. Even a "print "*";" doesn't work

    foreach my $line (@lines){
        #print "*"; works "in between". print "*" x $vari; does not.

        if ($line=~/xyz/){
            ......
            ......
        }
    close(LOGFILEhandle);
    }
}

【问题讨论】:

标签: perl foreach perl-module progress buffering


【解决方案1】:

我想建议Term::ProgressBar 模块以避免重新发明轮子。

#!/usr/bin/perl
use strict;
use warnings;

use Term::ProgressBar;

my @files = qw (file1 file2 file3 file4); 

my $progress = Term::ProgressBar->new(scalar @files);

for (0..@files) {
  $| = 1;
  sleep(1); #introducing sleep for demo purpose otherwise bar will fill up quickly
  #open the file, do some operations and when you are done
  #update the bar
  $progress->update($_);
}

【讨论】:

    【解决方案2】:

    您正在遭受缓冲。输出被缓冲,直到达到一定数量或您打印换行符。要更改此行为,只需添加

    $| = 1 ;
    

    在文件的顶部。这将为 STDOUT 打开自动刷新。 有不止一种方法可以做到这一点,鲍罗丁的建议更长一点,也不那么神秘:

    STDOUT->autoflush();
    

    【讨论】:

    • STDOUT-&gt;autoflush 更加不言自明,可用于任何给定的文件句柄。
    • “遭受缓冲”听起来像是一个常见问题:)。 5个字符使它工作。谢谢!
    • @Borodin 是的,你是对的......我在答案中添加了你的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    相关资源
    最近更新 更多