使用长度较短的打印语句覆盖打印语句

时间:2013-12-04 11:55:25

标签: perl printing foreach progress-bar

我有一个问题,我希望有人可以提供帮助...

我试图在foreach循环中覆盖print语句以创建一些进度条。

我在做什么:

my $arraySize = @listOfIps;
local $| = 1;   
my $counter = 0;
my $progressString;

print 'Progress: ';

foreach my $ip (@listOfIps) {

        $counter++;
        print "\b" x length($progressString) if defined $progressString;
        $progressString = "\r$counter / $arraySize - Working on $ip"; 
        print $progressString; 

        #does stuff here but thats irrelevant to the problem

}

我遇到的问题是,当foreach循环到达比前一个更短的IP时,例如10.0.0.1,它仍会显示上一个较长的打印语句留下的额外字符。

问题:

Progress: 3 / 10 - Working on 200.144.223.211

然后用数组中的下一个较小的ip地址覆盖这个print语句给出:

Progress: 4 / 10 - Working on 10.0.0.1223.211

依此类推......实际上它应该打印出来:

Progress: 4 / 10 - Working on 10.0.0.1

这样它就没有剩下的上一个字符中的任何字符。

我必须在这里看到一些真正可疑的东西,因为我无法看到为什么这不起作用的原因?

1 个答案:

答案 0 :(得分:3)

使用printf格式用空格填充IP字符串:

printf "\r$counter / $arraySize - Working on %-15s", $ip;

将数字15调整为最长IP的长度。如果你有一个变量,你可以像格式字符串一样使用它(感谢amon的共享):

printf ".... Working on %-*s", $length, $ip;

虽然这是相当多的,因为您可以使用printf控制所有可变长度字符串:

printf "\r%-*s / %-*s - Working on %-*s", 5, $counter, 5, $arraySize, 15, $ip;

\b转义显然是非破坏性退格,根据this answer.,它不会删除,这意味着它与{{ 1}}在你的情况下。