2009-05-27 6 views
6

Ich habe das folgende Skript, das eine Eingabedatei einnimmt, Ausgabedatei und ersetzt die Zeichenfolge in der Eingabedatei mit einer anderen Zeichenfolge und schreibt die Ausgabedatei aus.Wie kann ich Bulk suchen und durch Perl ersetzen?

Ich mag das Skript ändern, durch ein Verzeichnis von Dateien dh statt Aufforderung zur Eingabe und Ausgabe-Dateien zu durchlaufen, wird das Skript als Argument einen Verzeichnispfad wie C nehmen soll: \ temp \ allFilesTobeReplaced \ und Suche für eine Zeichenfolge x und ersetzen Sie sie durch y für alle Dateien unter diesem Verzeichnispfad und schreiben Sie die gleichen Dateien.

Wie mache ich das?

Danke.

$file=$ARGV[0]; 

open(INFO,$file); 
@lines=<INFO>; 
print @lines; 

open(INFO,">c:/filelist.txt"); 

foreach $file (@lines){ 
    #print "$file\n"; 
    print INFO "$file"; 
} 

#print "Input file name: "; 
#chomp($infilename = <STDIN>); 

if ($ARGV[0]){ 
    $file= $ARGV[0] 
} 

print "Output file name: "; 
chomp($outfilename = <STDIN>); 
print "Search string: "; 
chomp($search = <STDIN>); 
print "Replacement string: "; 
chomp($replace = <STDIN>); 

open(INFO,$file); 
@lines=<INFO>; 
open(OUT,">$outfilename") || die "cannot create $outfilename: $!"; 

foreach $file (@lines){  
    # read a line from file IN into $_ 
    s/$search/$replace/g; # change the lines 
    print OUT $_; # print that line to file OUT 
} 
close(IN); 
close(OUT); 

Antwort

11

Die Verwendung der perl einzigen Liner

perl -pi -e 's/original string/new string/' filename 

mit File::Find kombiniert werden, das folgende Einzel Skript (das ist eine Vorlage ich für viele solche Operationen verwenden) zu geben.

use File::Find; 

# search for files down a directory hierarchy ('.' taken for this example) 
find(\&wanted, "."); 

sub wanted 
{ 
    if (-f $_) 
    { 
     # for the files we are interested in call edit_file(). 
     edit_file($_); 
    } 
} 

sub edit_file 
{ 
    my ($filename) = @_; 

    # you can re-create the one-liner above by localizing @ARGV as the list of 
    # files the <> will process, and localizing $^I as the name of the backup file. 
    local (@ARGV) = ($filename); 
    local($^I) = '.bak'; 

    while (<>) 
    { 
     s/original string/new string/g; 
    } 
    continue 
    { 
     print; 
    } 
} 
1

Ich weiß, dass Sie ein einfaches Pro verwenden können, l Einzeiler von der Befehlszeile, wobei Dateiname ein einzelner Dateiname oder eine Liste von Dateinamen sein kann. Sie könnten wahrscheinlich kombinieren diese Antwort mit bgy die den gewünschten Effekt zu erhalten:

perl -pi -e 's/original string/new string/' filename 

Und ich weiß, es banal ist, aber das klingt viel wie sed, wenn Sie Gnu-Tools verwenden können:

for i in `find ./allFilesTobeReplaced`; do sed -i s/original string/new string/g $i; done 
2

Sie können dies mit dem -i param:

einfach alle Dateien wie gewohnt verarbeiten, sondern umfassen -i.bak:

#!/usr/bin/perl -i.bak 

while (<>) { 
    s/before/after/; 
    print; 
} 

Diese jede Datei verarbeitet werden soll, und Benennen Sie das Original in original.bak Und natürlich können Sie es als Einliner tun, wie von @Jamie Cook

-1

perl -pi -e 's # OLD # NEW # g' Dateiname. Sie können den Dateinamen durch das Muster ersetzen, das zu Ihrer Dateiliste passt.