perl – 读取整个文件,然后在内部编辑时打印?
大多数就地编辑的例子都是单行,它们遍历一个或多个文件,一次读取和打印一行.
我找不到任何将整个文件读入数组,根据需要修改数组,然后在使用^ I开关进行就地编辑时打印数组的示例.当我尝试从钻石运算符读取整个文件,编辑内容并打印整个内容时,我发现打印转到STDOUT而不是ARGVOUT并且ARGVOUT已关闭.我可以打开相同的文件输出然后打印到它,但我不确定我理解为什么这是必要的.这是一个例子: #!/usr/bin/perl use strict; use warnings; use 5.010; my $filename = 'test.txt'; push @ARGV,$filename; $^I = ".bk"; my @file = <>; #Read all records into array chomp @file; push @file,qw(add a few more lines); print join "n",@file; #This prints to STDOUT,and ARGVOUT is closed. Why? 运行上述操作会按预期备份test.txt文件,但将编辑后的test.txt保留为空,将编辑后的内容打印到STDOUT. 解决方法
见
perlrun .
当调用-i开关时,perl使用ARGVOUT作为默认文件句柄而不是STDOUT来启动程序.如果有多个输入文件,那么每次<>或< ARGV>或readline(ARGV)操作完成其中一个输入文件,它关闭ARGVOUT并重新打开它以写入下一个输出文件名. 一旦来自<>的所有输入耗尽(当没有更多文件要处理时),perl关闭ARGVOUT并再次将STDOUT恢复为默认文件句柄.或者正如perlrun所说 #!/usr/bin/perl -pi.orig s/foo/bar/; 相当于 #!/usr/bin/perl $extension = '.orig'; LINE: while (<>) { if ($ARGV ne $oldargv) { if ($extension !~ /*/) { $backup = $ARGV . $extension; } else { ($backup = $extension) =~ s/*/$ARGV/g; } rename($ARGV,$backup); open(ARGVOUT,">$ARGV"); select(ARGVOUT); $oldargv = $ARGV; } s/foo/bar/; } continue { print; # this prints to original filename } select(STDOUT); 一旦你说我的@file =<>并消耗所有输入,Perl将文件句柄关闭到备份文件并开始再次将输出定向到STDOUT. 我认为,解决方法是调用<>在标量上下文中并在每行之后检查eof(ARGV).当eof(ARGV)= 1时,您已阅读该文件中的最后一行,并且在调用<>之前您有一次机会打印再次: my @file = (); while (<>) { push @file,$_; if (eof(ARGV)) { # done reading current file @processed_file = &do_something_with(@file); # last chance to print before ARGVOUT gets reset print @processed_file; @file = (); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |