2009-05-27 17 views
6

Giriş dosyasında, çıktı dosyasında ve giriş dosyasındaki dizenin yerine başka bir dizeyle yer verilen ve çıkış dosyasına yazılan aşağıdaki komut dosyası var.Toplu arama ve Perl ile nasıl değiştirebilirim?

ben, script örneğin, C argüman olarak bir dizin yolu almalı dosyaları yani yerine giriş ve çıkış dosyaları için istemek bir dizine boyunca hareketlerini senaryoyu değiştirmek istiyorum: \ temp \ allFilesTobeReplaced \ ve arama Bir dize x için ve bu dizin yolu altındaki tüm dosyalar için y ile değiştirin ve aynı dosyaları yazın.

Bunu nasıl yaparım?

Teşekkürler.

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

cevap

11

kullanımı perl tek astarın

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

aşağıdaki tek bir komut dosyası (bu, bir çok bu tür operasyonlar için kullanımı bir şablon) vermek üzere, File::Find ile kombine edilebilir.

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

Ben basit bir Per kullanabilirsiniz biliyorum Komut satırından tek liner, burada dosya adı tek bir dosya adı veya dosya isimleri listesi olabilir. Muhtemelen istenen etkiyi elde etmek için Bgy cevabı ile birleştirmek olabilir:

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

Ve bunun basmakalıp olacak ama gnu araçları kullanabilirsiniz eğer bu, sed gibi bir çok geliyor:

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

:

Sadece normal olarak tüm dosyaları işlemek, ancak şunları i.bak: Bu, her dosyayı işlemek gerekir

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

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

ve original.bak için orijinali yeniden adlandırın Ve tabii ki, @Jamie Cook

-1

perl -pi -e '# OLD # NEW # g' dosya adı ile belirtildiği gibi bunu tek liner olarak yapabilirsiniz. Dosya adını, dosya listenize uyan desenle değiştirebilirsiniz.