2010-09-29 18 views
1

我的道歉,如果這是一個新手問題。我不是一個Perl開發人員,但我正在嘗試在自動化過程中使用它,而且我遇到了一些障礙。如何使用Perl在大文件中快速修復EBCDIC控制字符?

以下命令在我的Linux系統(Ubuntu 9.10 x64,Perl 5.10)上運行很快(幾秒鐘),但在Windows系統(Windows 2003 x86,Strawberry Perl 5.12.1.0)上速度非常慢。

perl -pe 's/\x00\x42\x00\x11/\x00\x42\x00\xf0/sgx' inputfile > outputfile 

查找/替換十六進制字符的圖案旨在以文件,它是爲2GB 500MB之間的尺寸以固定托架EBCDIC控制字符。我不確定這是否是最有效的方法,但它似乎有訣竅,只要它能在Windows系統上快速運行,就需要運行。

有什麼想法?

+1

什麼是你的Windows外殼程序?我不認爲單引號在標準CMD shell中作爲參數分隔符工作。 – mob 2010-09-29 19:12:54

+0

只是標準的CMD外殼。過去我沒有單引號的問題,但是我還沒有在Perl之前使用過。我現在用雙引號運行,並顯示相同的行爲。 – rickyboone 2010-09-29 19:48:31

+0

所以你發佈的命令行在Windows上工作,但它只是工作緩慢? – mob 2010-09-29 20:00:32

回答

3

請注意,Windows上的文本和二進制文件存在區別。文本文件會受到自動EOL轉換的影響,我認爲它可能會增加運行時間,並且可能會擾亂您的二進制替換(大概不是這裏的情況)。

此外,使用/sx這個替代項沒有意義。

我認爲問題的核心在於:使用-p開關,您應該逐行處理輸入。文件中的第一個EOL(由perl理解)在哪裏?你是否試圖在內存中讀取一個巨大的字符串,對其執行s///並寫出來?

如何使用下面的腳本:

#!/usr/bin/perl 

use strict; use warnings; 
$/ = "\x00\x42\x00\x11"; 
$\ = "\x00\x42\x00\xf0"; 

while (<>) { 
    chomp; 
    print; 
} 

而且,你絕對需要在Windows上使用雙引號。比較和對比:

C:\Temp> perl -pe 's/perl/merl/' t.pl 
#!/usr/bin/perl 
...
C:\Temp> perl -pe "s/perl/merl/" t.pl 
#!/usr/bin/merl 
...
+2

聰明! <! - padpadpad - > – 2010-09-29 20:31:57

+0

我的意圖是讓perl將輸入和輸出視爲二進制,而不需要EOL轉換。 – rickyboone 2010-09-29 21:00:01

+1

(抱歉,在這些註釋中忘記「enter」會立即發送它們......)我在上面運行的腳本(perl test.pl < input >輸出)似乎在文件的末尾添加了一個額外的\ x42 \ x00 \ xf0,儘管它速度更快,並使文件中的所有內容都正確無誤。我是否有理由認爲這是由於Windows正在進行EOL轉換?我不應該使用STDIN和STDOUT並以二進制模式調用特定的輸入/輸出文件嗎? – rickyboone 2010-09-29 21:03:33