2011-05-26 105 views
4

我想刪除以HPL_開頭的文本文件中的所有行我已經完成了此操作並可以打印到屏幕上,但是當我嘗試寫入文件時,新文件中打印的修改文本的一行。請任何幫助!將問題打印到新文件中的Perl問題

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; 
+2

沒有人願意,也不應該永遠有,調試Perl代碼沒有'use strict;在其頂部使用警告。即使嘗試也是純粹的瘋狂。在一個現代化的Perl編程環境中,你也希望識別你使用'use v5.12'或whatnot運行的Perl的版本,並且如果你的版本是5.10.1或更好,你也可以使用'use autodie'。否則,這太難了。 – tchrist 2011-05-26 18:13:06

回答

7

你只是想刪除所有以HPL_開頭的行嗎?這很容易!

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

是的,它真的只是一個班輪。 :-)

+0

好的答案,我upvoted,但我也打賭,這只是整個問題的一部分,實際問題更復雜。換句話說,你可能已經回答了這個問題,但不是真正的需要。不批評;只是猜測。 – MJB 2011-05-26 17:32:29

+0

嗯,好吧,那比我想象的要容易得多!感謝:-) – 2011-05-26 18:09:44

+1

這不會留下以前的'HPL_'空行嗎?當我嘗試它時,我必須明確添加'\ n'來刪除空白行。 – TLP 2011-05-26 22:06:11

4

如果你不想使用一個內膽,重新寫了「寫入文件」部分如下:

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); 

注意你是如何open()每次荷蘭國際集團的文件通過循環。這導致文件只包含最後一行,因爲使用open()>表示「覆蓋文件中的內容」。這是你代碼的主要問題。

編輯:另一方面,你想清理你的代碼。正如我所示,使用詞法文件句柄。總是添加tchrist發佈在每個Perl程序頂部的三行代碼。使用三運營商版本open()。不要將整個文件寫入數組,因爲如果您嘗試讀取大文件,可能會導致計算機內存不足。您的程序可以被重新寫爲:

#!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); 

注意你不需要添加or die ...open()功能如何與use autodie,作爲autodie編譯處理,對你。

+0

+1文件和內存消耗的優點。 – 2011-05-26 17:51:08

+0

很確定在打印中使用詞法文件句柄需要將它們包裝在{和}中。 – 2011-05-26 17:52:13

+0

@Rob:不,他們沒有。也許在Perl的非常古老的版本中,但至少在5.6天以後纔會出現。你只需要這樣做,如果你正在做一些事情,像在數組中存儲文件句柄,在這種情況下,你必須做一些事情,比如'print {$ fhs [1]} $ line'。另見[perldoc print](http://perldoc.perl.org/functions/print.html)。 – CanSpice 2011-05-26 18:01:39

4

您的代碼問題在於,您在行處理循環中打開了用於輸出的文件,由於您使用open的「>」形式,每次打開文件時都會打開文件,刪除以前的任何內容。

將open()的調用移動到文件頂部,在循環上方,它應該可以工作。

此外,我不確定你的意圖,但在你的例子的第4行,你重新打開你的輸入文件進行寫入(使用'>'),這也會破壞它包含的任何東西。

作爲一個側面說明,你可以嘗試在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); 
+1

這是正確的,該文件被循環中的每個open()覆蓋。前兩個打開是好的,因爲該文件在關閉並重新打開之前已經加載到數組中。請注意,要以「追加」模式打開文件並避免覆蓋其內容,請打開「>> $ file」。 (在這個例子中不是一個好主意) – 2011-05-26 17:59:01