2009-05-21 2 views
0

Ich habe ein Projekt, in dem ich Ordner, Unterordner und Dateien habe. Ich muss das Wort Masi durch das Wort Bond in jeder Datei ersetzen.Das Wort im Inhalt eines bestimmten Ordners kann nicht durch Sed/Python/Perl ersetzt werden.

ich folgende Sed-Skript aufgerufen laufen ersetzen erfolglos

s/Masi/Bond/ 

in Zsh von

sed -f PATH/replace PATH2/project/** 

Es gibt mir alle Dateien, auch diejenigen, die als Ausgang nicht Masi haben.

Sed ist nicht unbedingt das beste Werkzeug für die Aufgabe. Ich interessiere mich für Python und Perl.

Wie würden Sie den Ersatz in Sed/Perl/Python, so tun, dass nur die Dateiinhalte geändert werden?

+0

Haben Sie die Zeichenfolge in den Dateinamen oder in den Dateiinhalt ersetzen? – fmarc

+0

Was macht Sie denken, sed kann Verzeichnisse umbenennen? Warum verwenden Sie nicht "mv" oder einen anderen Befehl, der Dateien umbenennt? –

+0

@fmarc: Ich möchte die Zeichenfolge im Dateiinhalt ersetzen, nicht in den Dateinamen. –

Antwort

12

Um das Wort in allen oben

im aktuellen Verzeichnis und deren Unter gefundenen Dateien zu ersetzen
perl -p -i -e 's/Masi/Bond/g' $(grep -rl Masi *) 

Das wird, wenn Sie Räume haben nicht arbeiten Dateinamen. Safer zu tun:

find . -type f -exec perl -p -i -e 's/Masi/Bond/g' {} \; 

oder in Mac, die Leerzeichen in Dateinamen

find . -type f -print0 | xargs -0 perl -p -i -e 's/Masi/Bond/g' 

Erläuterungen

  • -p bedeutet, Druck oder sterben
  • -i „bedeutet, hat dies nicht tun Machen Sie irgendwelche Backup-Dateien "
  • -e können Sie Perl ausführen c Ode in der Befehlszeile
+1

+1 für einen ausgezeichneten Grep-Trick, um nur die Dateien zu ändern, die geändert werden müssen. –

+3

+1 Du hast mich dazu geschlagen. Das ist mein Lieblings-Perl-One-Liner. Die Frage ist: Nachdem Sie mit diesem einen Liner hunderte von Dateien in wenigen Sekunden repariert haben, arbeiten Sie weiter oder nehmen Sie den Rest des Tages, denn so lange würde jemand mit Notizblock brauchen? –

+0

-i bedeutet, dass der Fall keine Rolle spielt. Was sind die anderen Optionen -p und -e? Ich habe keine Erklärungen für sie bei Mann Perl gefunden. –

3

Warum nicht einfach die -i Option (man sed) an sed übergeben und damit fertig sein? Wenn Masi nicht in einer Datei gefunden wird, wird die Datei nur ohne Änderung überschrieben. Oder fehlt mir etwas?

Wenn Sie nicht wollen, um den Inhalt inline Dateien ersetzen (was die -i tun wird) Sie können genau das tun, wie Sie jetzt sind, aber eine grep & xargs vor ihm werfen:

grep -rl Masi PATH/project/* | xargs sed -f PATH/replace 

Viele Optionen, aber tun nicht schreiben Sie eine ganze Perl-Skript für diese (Ich gebe dem Einzeiler einen Pass;)). find, grep, sed, xargs usw. wird immer flexibler sein, IMHO.

Als Antwort auf Kommentar:

grep -rl Masi PATH/project/* | xargs sed -n -e '/Masi/ p' 
+0

@Sean: Wie können Sie sehen, welche Zeilen geändert werden, bevor Sie den Befehl ausführen? –

+0

Ich habe meine Antwort aktualisiert, um Ihren Kommentar zu adressieren. –

+0

@Sean: Ist Ihre Lösung in kritischen Umgebungen sicher, ähnlich wie http://stackoverflow.com/questions/894802/unable-to-replace-the-word-in-a-iven-folders-content-by-sed- Python-Perl/894982 # 894982? Ich bin mir nicht sicher, wie sicher es ist, die Befehle zu kombinieren. –

0

Eine Lösung auf Windows

getestet

Benötigt CPAN-Modul File :: Slurp.Funktioniert mit Standard-Unix-Shell-Wildcards. Wie ./replace.pl PATH/replace.txt PATH2/ersetzen *

#!/usr/bin/perl 

use strict; 
use warnings; 
use File::Glob ':glob'; 
use File::Slurp; 
foreach my $dir (@ARGV) { 
    my @filelist = bsd_glob($dir); 
    foreach my $file (@filelist) { 
    next if -d $file; 
    my $c=read_file($file); 
    if ($c=~s/Masi/Bond/g) { 
     print "replaced in $file\n"; 
     write_file($file,$c); 
    } else { 
     print "no match in $file\n"; 
    } 
    } 
} 
+0

Die Shell-Platzhalter werden von der Shell gehandhabt. Die Behandlung in Perl ist nicht erforderlich. –

+2

Hängt vom Betriebssystem ab :) - Ich teste das unter Windows. –

+1

Ich bin mit Alexandr hier. Ich habe noch nie gesehen, dass die Windows-Shell eine Platzhaltererweiterung hat. – pjf

3

einen Ordner umbenennen voller Dateien:

use warnings; 
use strict; 
use File::Find::Rule; 

my @list = File::Find::Rule->new()->name(qr/Masi/)->file->in('./'); 

for(@list){ 
    my $old = $_; 
    my $new = $_; 
    $new =~ s/Masi/Bond/g; 
    rename $old , $new ; 
} 

Ersetzen Strings in Dateien

use warnings; 
use strict; 
use File::Find::Rule; 
use File::Slurp; 
use File::Copy; 

my @list = File::Find::Rule->new()->name("*.something")->file->grep(qr/Masi/)->in('./'); 

for(@list){ 
    my $c = read_file($_); 
    if ($c =~ s/Masi/Bond/g;){ 
    File::Copy::copy($_, "$_.bak"); # backup. 
    write_file($_ , $c); 
    } 
} 
  • strict (Kern) - Perl-Pragma, um unsichere Konstrukte einzuschränken
  • warnings (Kern) - Perl Pragma optional Warnungen steuern
  • File::Find::Rule - Alternative Schnittstelle File :: Find
  • File::Find (Kern) - Traverse einem Verzeichnisbaum.
  • File::Slurp - Effizientes Lesen/Schreiben von kompletten Dateien
  • File::Copy (Kern) - Kopieren von Dateien oder Dateihandies
+0

Benennt das letzte Skript alle Dateien einschließlich der Unterverzeichnisse um? - - Chaos gab mir sein ähnliches Skript unter http://lostsouls.org/grimoire_convert_all. Dein Skript scheint kürzer zu sein. Das deutet darauf hin, dass es sich nicht um reines Perl handelt. Welche Teile würden Sie in Ihrem Skript verbessern, um es in kritischen Umgebungen sicher zu machen? –

+1

@Masi, ähm, sicher ist es reines Perl, es benutzt nur Module um das schwere Heben zu machen und sie machen die ganze harte Arbeit, die für mich gelöst wurde. File :: Find :: Rule ist absolut sicher für kritische Umgebungen, möglicherweise * mehr *, als es mit manuellem opendir zu erledigen, weil es mindestens * getestet * auf * mehreren * Plattformen funktioniert wie erwartet. –

0
import glob 
import os 

# Change the glob for different filename matching 
for filename in glob.glob("*"): 
    dst=filename.replace("Masi","Bond") 
    os.rename(filename, dst) 
Verwandte Themen