Editați fișierele în loc cu perl de la powerhell

Am o listă de fișiere files.txt într-un director. Vreau să rulez o înlocuire a textului prin fiecare fișier.

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

Dar Perl nu-i place sa faca asta fara sa faca un backup.

Nu se poate face editarea în locația fără backup.

Așa că am adăugat .bak la -i:

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

Și acum se plânge:

Nu se poate deschide scriptul perl ".bak": Nici un astfel de fișier sau director

Ce am lipsit?

ACTUALIZAȚI:

Ceea ce aș prefera este o modalitate de a face acest lucru fără o coajă în întregime. Pot să fac această buclă în perl doar cu $ ^ I ?

0
Mulțumesc, Chris! Ai avut dreptate că am vrut să d \ d {1,4}. Dar introducerea lui -i.bak nu a schimbat eroarea. Eu folosesc perl DWIM 5.14.2.
adăugat autor wdkrnls, sursa
@ EBGreen, @ BartekB: Bine, o voi încerca.
adăugat autor wdkrnls, sursa
Am încercat: Foreach ($ i în $ f) {$ i -replace "(\ d {1,4}) -", "$ 1 -"} dar nu a schimbat efectiv fișierele. Nu -localizează numai înlocuirea șirului și nu editarea în loc ca pe scriptul perl ar avea?
adăugat autor wdkrnls, sursa
@Chris Charley, Nu este adevărat. Perl pe Windows acceptă -pi.bak perfect. Acestea fiind spuse, PowerShell pare să treacă altceva decât -pi.bak (mai exact, -pi .bak ), astfel încât să fie lucrurile potrivite pentru PowerShell .
adăugat autor ikegami, sursa
@wdkrnls, perl -pi.bak -we "s/(\ d {0,4}) -/$ 1 -/g" este bine pentru cmd . Aceasta pare să fie o problemă specifică pentru PowerShell.
adăugat autor ikegami, sursa
Perl primește niște spații între -i și .bak . Nu știu de ce. (Nu aveți și nu ați folosit niciodată PowerShell.)
adăugat autor ikegami, sursa
Sunt curios de ce nu faceți totul în PS?
adăugat autor EBGreen, sursa
Va trebui să conduceți șirul rezultat înapoi la fișier, astfel încât ceva ($ i în $ f) {$ i -replace "(\ d {1,4}) -", "$ 1 -" | Out-fișier $ i -Force}
adăugat autor EBGreen, sursa
Problema aici este că parserul PowerShell va încerca să vă analizeze codul Perl și, evident, îl va face inutil odată ce îl va trece la executabilul perl ... Există câteva moduri în jurul acestuia, inclusiv crearea de wrapper pentru perl sau utilizarea procesului de pornire magic pentru a forța PS să ignore token-urile care au înțeles diferit în Powershell (cum ar fi -foo). Dar nu văd de ce, dacă utilizați deja PowerShell, nu folosiți: {$ i -replace '(\ d {1,4})', '$ 1'} sau ceva de-a lungul acestor linii în loc de perl. .? :)
adăugat autor BartekB, sursa
Pe Windows, este necesar să puneți comutatorul -i.bak pe cont propriu. Cum ar fi, perl -i.bak -pwe ... Sunteți sigur că doriți \ d {0.4} și nu \ d {1,4}
adăugat autor Chris Charley, sursa

2 răspunsuri

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 matches more than 0-9 when /a isn't used, so you probably want

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

Rețineți că cele de mai sus nu împiedică potrivirea a 5 cifre după cum doriți. Pentru a face acest lucru, utilizați:

 s/(?
0
adăugat

ikegami a fost absolut corect. În powerhell -i.bak este interpretat ca -i. Soluția este de a forța forțele de putere să le transmită ca argument unic.

Ca     perl '-pi.bak' -we .... # închideți-le în citate simple.

0
adăugat