2009-05-27 15 views
6

Mam następujący skrypt, który pobiera plik wejściowy, plik wyjściowy i zamienia ciąg znaków w pliku wejściowym na inny ciąg i wypisuje plik wyjściowy w postaci .Jak mogę przeprowadzić wyszukiwanie zbiorcze i zastąpić je Perl?

Chcę zmienić skrypt do przechodzenia poprzez katalogu plików czyli zamiast monitowanie dla plików wejściowych i wyjściowych, skrypt powinien jako argument ścieżkę katalogu, takich jak C: \ Temp \ allFilesTobeReplaced \ i wyszukiwania dla ciągu x i zamień go na y dla wszystkich plików pod tą ścieżką katalogową i wypisz te same pliki.

Jak to zrobić?

Dzięki.

$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); 

Odpowiedz

11

Zastosowanie od perl pojedynczą warstwę

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

można łączyć z File::Find, otrzymując następujące pojedynczego skryptu (to jest szablon używać do wielu z tych operacji).

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

wiem, można użyć prostego Per l jeden wiersz z linii poleceń, gdzie nazwa pliku może być pojedynczą nazwą pliku lub listą nazw plików. Prawdopodobnie mógł połączyć to z odpowiedzią BGY, aby uzyskać pożądany efekt:

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

I wiem, że to banalne, ale brzmi to trochę jak sed, jeśli można użyć GNU narzędzia:

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

Można to zrobić z -i param:

Wystarczy przetwarzać wszystkie pliki jako normalne, ale to -i.bak:

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

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

ten powinien przetwarzać każdy plik i zmień nazwę oryginału na original.bak Oczywiście można to zrobić jako jednolinijkową, o czym wspomina @Jamie Cook

-1

perl -pi -e # # OLD # NEW # g 'filename. Możesz zastąpić nazwę pliku wzorcem, który pasuje do twojej listy plików.

Powiązane problemy