2012-06-04 56 views
1

我有一個目錄中的文件files.txt的列表。我想通過每個文件運行一個文本替換。使用perl從powershell編輯文件

$f = (get-content files.txt) 
Foreach ($i in $f) { perl -pi -we "s/(\d{0,4})- /$1 - /g" $i } 

但是,perl並不喜歡在沒有做備份的情況下做到這一點。

不能在沒有備份的情況下進行編輯。

所以我加入了名爲.bak到-i:

$f = (get-content files.txt) 
Foreach ($i in $f) { perl -pi.bak -we "s/(\d{0,4})- /$1 - /g" $i } 

而現在抱怨:

無法打開perl腳本名爲 「.bak」:沒有這樣的文件或目錄

我錯過了什麼?

UPDATE:

我寧願是一個辦法做到這一點,而不完全是一個外殼。我可以在Perl中用$^I做這個循環嗎?

+0

在Windows上,需要自行放置-i.bak開關。像,perl -i.bak -pwe ...你確定你想要\ d {0.4}而不是\ d {1,4} –

+0

@Chris Charley,這是不正確的。 Windows上的Perl接受'-pi.bak'完全正確。也就是說,PowerShell似乎會傳遞除'-pi.bak'(特別是'-pi .bak')之外的東西,所以這可能是* PowerShell *的正確選擇。 – ikegami

+0

@wdkrnls,'perl -pi.bak -we「s /(\ d {0,4}) -/$ 1 -/g」'適用於'cmd'。這似乎是PowerShell特有的問題。 – ikegami

回答

1
my $qfn = 'files.txt'; 
open(my $fh, '<', $qfn) 
    or die("Can't open file list \"$qfn\": $!\n"); 

local @ARGV = <$fh>; 
local $^I = '.bak'; 
local $_; 
while (<>) { 
    s/(\d{0,4})- /$1 - /g; 
    print; 
} 

\d比賽比0-9更當/ A沒有使用,所以你可能想

s/(\d{0,4})- /$1 - /ag; 
    -or- 
s/([0-9]{0,4})- /$1 - /g; 

注意上面並不妨礙5位被作爲匹配你似乎想要。要做到這一點,使用:

s/(?<![0-9])([0-9]{0,4})- /$1 - /g; 

現在,沒有理由以自己更換號碼,當你知道\K

s/(?<![0-9])[0-9]{0,4}\K-/- /g; 

最後,我們也可以擺脫重複的-

s/(?<![0-9])[0-9]{0,4}\K(?=-)/ /g; 
1

ikegami是絕對正確的。在powershell -i.bak中解釋爲-i .bak。解決方案是強制powershell將其作爲單個參數傳遞。

像 perl'-pi.bak'-we ....#將它們括在單引號中。