简体   繁体   English

Perl 打印 output 到新文件时出现问题

[英]Perl problems printing output to a new file

I want to remove all lines in a text file that start with HPL_ I have acheived this and can print to screen, but when I try to write to a file, I just get the last line of the amended text printed in the new file.我想删除以 HPL_ 开头的文本文件中的所有行,我已经实现了这一点并且可以打印到屏幕上,但是当我尝试写入文件时,我只是将修改后的文本的最后一行打印在新文件中。 Any help please!请提供任何帮助!

open(FILE,"<myfile.txt"); 
@LINES = <FILE>; 
close(FILE); 
open(FILE,">myfile.txt"); 
foreach $LINE (@LINES) { 
@array = split(/\:/,$LINE); 


my $file = "changed";

open OUTFILE, ">$file" or die "unable to open $file $!";

print OUTFILE $LINE unless ($array[0] eq "HPL_");

} 
close(FILE); 
close (OUTFILE);




exit;

You just want to remove all lines that start with HPL_ ?您只想删除所有以HPL_开头的行吗? That's easy!这很容易!

perl -pi -e 's/^HPL_.*//s' myfile.txt

Yes, it really is just a one-liner.是的,它确实只是一条线。 :-) :-)

If you don't want to use the one-liner, re-write the "write to file" portion as follows:如果您不想使用单行,请重新编写“写入文件”部分,如下所示:

my $file = "changed";
open( my $outfh, '>', $file ) or die "Could not open file $file: $!\n";
foreach my $LINE (@LINES) { 
  my @array = split(/:/,$LINE);
  next if $array[0] eq 'HPL_';
  print $outfh $LINE;
}
close( $outfh );

Note how you are open() ing the file each time through the loop.请注意每次通过循环时您是如何open()文件的。 This is causing the file to only contain the last line, as using open() with > means "overwrite what's in the file".这导致文件只包含最后一行,因为将open()>一起使用意味着“覆盖文件中的内容”。 That's the major problem with your code as it stands.这是您的代码的主要问题。

Edit: As an aside, you want to clean up your code.编辑:顺便说一句,你想清理你的代码。 Use lexical filehandles as I've shown.如我所示,使用词法文件句柄。 Always add the three lines that tchrist posted at the top of every one of your Perl programs.始终添加 tchrist 在每个 Perl 程序顶部发布的三行。 Use the three-operator version of open() .使用open()的三运算符版本。 Don't slurp the entire file into an array, as if you try to read a huge file it could cause your computer to run out of memory.不要将整个文件放入数组中,就好像您尝试读取一个大文件可能会导致您的计算机用完 memory。 Your program could be re-written as:您的程序可以重写为:

#!perl

use strict;
use autodie; 
use warnings FATAL => "all";

my $infile = "myfile.txt";
my $outfile = "changed.txt";

open( my $infh, '<', $infile );
open( my $outfh, '>', $outfile );
while( my $line = <$infh> ) {
    next if $line =~ /^HPL_/;
    print $outfh $line;
}
close( $outfh );
close( $infh );

Note how with use autodie you don't need to add or die... to the open() function, as the autodie pragma handles that for you.请注意如何use autodie ,您不需要添加or die...open() function,因为autodie pragma 会为您处理。

The issue with your code is that you open the file for output within your line-processing loop which, due to your use of the '>' form of open, opens the file each time for write, obliterating any previous content.您的代码的问题是您在行处理循环中打开 output 的文件,由于您使用了“>”形式的打开,因此每次都打开文件进行写入,从而消除任何以前的内容。

Move the invocation of open() to the top of your file, above the loop, and it should work.将 open() 的调用移到文件顶部,循环上方,它应该可以工作。

Also, I'm not sure of your intent but at line 4 of your example, you reopen your input file for write (using '>'), which also clobbers anything it contains.另外,我不确定您的意图,但是在示例的第 4 行,您重新打开输入文件以进行写入(使用“>”),这也会破坏它包含的任何内容。

As a side note, you might try reading up on Perl's grep() command which is designed to do exactly what you need, as in:作为旁注,您可以尝试阅读 Perl 的 grep() 命令,该命令旨在完全满足您的需求,如:

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

open(my $in, '<', 'myfile.txt') or die "failed to open input for read: $!";
my @lines = <$in> or die 'no lines to read from input';
close($in);

# collect all lines that do not begin with HPL_ into @result
my @result = grep ! /^HPL_/, @lines; 

open(my $out, '>', 'changed.txt') or die "failed to open output for write: $!";
print { $out } @result;
close($out);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM