Frage

Ich habe das folgende Skript, das in einer Eingabedatei, Ausgabedatei nimmt und ersetzt die Zeichenfolge in der Eingabedatei mit einem anderen String und schreibt die Ausgabedatei.

Ich mag das Skript ändern, durch ein Verzeichnis von Dateien zu durchqueren das heißt, anstatt für Ein- und Ausgabedateien von auffordert, sollte das Skript nehmen als Argument eines Verzeichnispfad, wie beispielsweise C: \ temp \ allFilesTobeReplaced \ und Suche nach einem String x und ersetzen Sie es mit y für alle Dateien unter dem Verzeichnispfad und schreiben Sie die gleichen Dateien.

Wie kann ich das tun?

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);
War es hilfreich?

Lösung

Die Verwendung des Perl einzigen Liner

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

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

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;
    }
}

Andere Tipps

Sie können dies tun, mit dem -i param:

So verarbeiten alle Dateien, die als normal, aber umfassen -i.bak:

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

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

Dies sollte jede Datei, verarbeitet und die ursprünglichen umbenennen, um original.bak Und natürlich können Sie es als Einzeiler tun, wie durch @Jamie Koch erwähnt

Versuchen Sie, diese

#!/usr/bin/perl -w

@files = <*>;
foreach $file (@files) {
  print $file . '\n';
}

Nehmen Sie auch einen Blick in Perl glob:

Ich weiß, dass Sie einen einfaches Perl Einzeiler aus der Befehlszeile verwenden können, wobei Dateiname ein einzelner Dateiname oder eine Liste von Dateinamen sein. 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 ist banal, aber das viel wie sed klingt, wenn Sie Gnu-Tools verwenden können:

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

perl -pi- 's # OLD # NEU # g' Dateiname. Sie können Dateinamen mit dem Muster ersetzen, die Ihre Dateiliste entspricht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top