2014-01-16 29 views
1

我有一個文本文件,下面的線爲例添加標題到一個文本文件中的Perl

This is line 
This is line with test 
This is ine with 2test 
This is line 2 
This is line 3 
This is line with 3test 
This is line 4 
This is line with 4test 

現在我想一個代碼來更改文本文件,如下所示:

Lines with test 
This is line with test 
This is ine with 2test 
This is line with 3test 
This is line with 4test 

Lines without test 
This is line 
This is line 2 
This is line 3 
This is line 4 

我正在使用下面的代碼。我假設我的代碼會打印每行的標題,但由於某些錯誤,我無法執行代碼。 你能幫我嗎?

#!/usr/bin/perl 
use strict; 
use warnings; 
open(FH, '<filetest.txt'); 
my @queues = <FH>; 
close(FH); 
open(OFH,'>testfile.txt'); 
my $name; 
foreach $name(@queues) 
{ 
if($name =~ 'test') 
{ 
print OFH "Lines with test\n"; 
print OFH $1; 
} 
else{ 
print OFH "Lines without test\n"; 
print OFH $1; 
} 
close(OFH); 
} 

注:我糾正了錯誤刪除的語法錯誤,但仍然沒有什麼被寫入到文件TESTFILE.TXT

+0

「由於一些錯誤」 - 語法錯誤,要準確。提示:錯誤的來源可能會在報告錯誤的位置之前發生。還要注意,'#'開始一個行註釋,並且這個正則表達式必須使用某種類型的正則表達式,比如'/ foo /'。但即使在那之後,你的代碼也存在各種bug。 (1)一次讀取和寫入同一個文件是行不通的。 (2)您對'open'使用陳舊的語法,並且不執行任何錯誤檢查。 (3)'$ 1'不會被填充。使用'$ _'。 (4)輸出*每行*的標題。相反,首先將這些行放入數組中。 (...) – amon

回答

2

有一試:

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

my $infile = 'filetest.txt'; 
my $outfile = 'testfile.txt'; 

# use 3-arg open and if open succeeded 
open my $fh_in, '<', $infile or die "Unable to open file '$infile' for reading: $!"; 

my @with_test; 
my @without_test; 
while (<$fh_in>) { 
    if (/test/) { 
     push @with_test, $_; 
    } else { 
     push @without_test, $_; 
    } 
} 
close $fh_in; 

open my $fh_out, '>', $outfile or die "Unable to open file '$outile' for writting: $!"; 
print $fh_out "Lines with test\n"; 
print $fh_out @with_test; 
print $fh_out "Lines without test\n"; 
print $fh_out @without_test; 

close $fh_out; 
+0

謝謝M42。這是行得通的。我實際上已經改變了你的腳本,所以輸出寫入了infile本身。我不需要infile的副本。你有沒有看到這樣做的問題? – user3164754

+0

@ user3164754:不客氣。您可以使用相同的文件進行輸入和輸出,因爲輸入文件在打開輸出之前已關閉。但我會在處理之前做一個備份... – Toto

1

我沒有測試過這一點。我們的想法是寫了「帶測試」行到文件立即 的「不含測試」行存儲(在所謂的「無」的陣列),直到程序結束,然後寫入

#!/usr/bin/perl 
use strict; 
use warnings; 
open(FH, '<filetest.txt'); 
my @queues = <FH>; 
close(FH); 
open(OFH,'>testfile.txt'); 
my $name; 
my @without=(); 
foreach $name(@queues) 
{ 
if($name =~ 'test') 
{ 
    print OFH $name; 
} 
else{ 
    push @without, $name; 
} 
print OFH "\n\nlines without\n"; 
print OFH @without; 

} 
+0

'push'語法不是這樣的,你已經顛倒了參數的順序! – Toto

+0

@ M42你是對的,修復它 – Vorsprung

0

也在閱讀文件句柄之前,您應該添加local $/。 檢查了這一點: how to read the whole file. 匹配格式應該是這樣的:if($somestr =~ /#/)。 ,你不應該關閉循環中的文件句柄。

#!/usr/bin/perl 

use strict; 
use warnings; 
local $/; 
open(FH, 'file#.txt'); 
my $s; 
$s = <FH>; 
close(FH); 
open(FH, '>file#.txt'); 
my @queues = split(/\n/, $s); 
my @arr; 
my @arr2; 
for($s=0; $s<$#queues+1; $s++) 
{ 

    if($queues[$s] =~ /#/) 
    { 
     push(@arr, $queues[$s]."\n"); 
    } 
    else 
    { 
     push(@arr2, $queues[$s]."\n"); 
    } 
} 
print FH "lines with #\n"; 
print FH @arr; 
print FH "lines without #\n"; 
print FH @arr2; 
+0

爲什麼你要本地化'$ /'然後用'split'重新實現它的功能?單獨留下'$ /'並將整個文件讀入數組會更有效率。另外爲什麼你會使用一個(潛在的越野車)C風格的循環而不是foreach循環?你也不應該重複使用'$ s'。這個答案的唯一部分比問題更好的是你將元素推入兩個數組中。 –

相關問題