• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] Suchen + Ersetzen in mehreren Dateien

Hallo Leute,

Habe folgendes Problem:

Ich muß in einer ganzen Reihe von Dateien mehrere Worte suchen und durch jeweils andere ersetzen.

Bisher habe ich soetwas in einer einzelnen Datei immer über den Umweg eines Editors erledigt. Aber hier geht es jetzt um Dutzende von Dateien, in denen ich jeweils 4 Worte durch andere ersetzen muß.

Wie kann ich auf einfachste Weise alle Dateien innerhalb eines Verzeichnisses nach bestimmten Begriffen durchsuchen und diese ersetzen?

In der Forensuche habe ich einiges bzgl. ähnlicher Probleme gefunden. Da wurde auf "sed" verwiesen. Leider halfen mir die Seiten nicht wirklich weiter, es waren eigentlich eher spezielle Fälle (oder ich habe die richtigen Forenbeiträge nicht gefunden).

PS: Falls das was hilft: Es geht um fehlerhafte Handhistories eines Pokerraumes, die zwar auf englisch sind, in denen aber die Kartenfarben auf deutsch sind. Für Analysetools daher unbrauchbar. Wenn ich die Begriffe also ändere (z.B. Karo gegen Diamond, etc.), dann sollte das Analyse-Tool reibungslos funktionieren - hoffe ich jedenfalls. ;)
 
Hallo,

Code:
sed -i 's/Karo/Diamond/g' <wo>/*
oder vielleicht

Code:
sed -i 's/Karo/Diamond/g' <wo>/*.txt
(das 'g' sorgt dafür dass auch mehrfach vorkommende 'Karo' auf einer Zeile ersetzt werden)

Funktioniert aber nicht wenn das gesuchte Wort getrennt auf zwei Zeilen ist:

Code:
xyz Ka-
ro abc
Gruss,
Roland
 

framp

Moderator
Teammitglied
Fuetter doch mal Tante Googgle mit 'replace string in files linux tool' . Kommen eine Menge Hits die gut ausehen ;)
 
Ist schon so, "sed" ist dafür das Mittel der Wahl.
Manche nehmen dafür auch einen Perl-Einzeiler, der aber im Prinzip (fast) dieselbe Ersetzungssyntax wie sed verwendet.
Insofern, es lohnt sich, sich mit dieser Syntax ("Reguläre Ausdrücke") ein bißchen vertraut zu machen.
 
Hallo,

ich mach das immer mit php:
Das Script durchsucht auch gleich alle Unterverzeichnisse.

Code:
#!/usr/bin/php
<?php

$dirs = array();

function suchen($verzeichnis) {
  global $dirs;
  $dir_inh=scandir($verzeichnis);
  chdir($verzeichnis);
  foreach($dir_inh as $inh) {
    if(substr($inh, 0, 1) == '.' OR substr($inh, -1) == '~') {
      continue;
    } elseif(is_dir($inh)) {
      $dirs[] = getcwd()."/".$inh;
    } elseif(stripos($inh, ".php")) {
      $temp = file_get_contents($inh, false, NULL, -1, 50);
      if(stripos($temp, "#!/usr/bin/php") !== false) {
        copy($inh, $inh.'.bak');
        file_put_contents(getcwd()."/".$inh, str_replace("suchtext", "ersetzung", file_get_contents($inh)));
        echo getcwd()."/".$inh."\n";
      }
    }
  }
}

if($_SERVER['argc']>1 AND is_dir($_SERVER['argv'][1])) {
  $dirs = array($_SERVER['argv'][1]);
  for($i=0; $i<count($dirs); $i++) {
    suchen($dirs[$i]);
  }
} else {
echo " -> Bitte folgende Syntax verwenden:
 -> ".basename($_SERVER['argv'][0])." [/]verzeichnis/zum/durchsuchen\n";
}

?>

Diese Beispiel sucht halt nur nach Dateien mit *.php Endung, kann man ja anpassen.

Funktioniert bei mir ganz gut.

huby
 
huby schrieb:
Hallo,

ich mach das immer mit php:
Das Script durchsucht auch gleich alle Unterverzeichnisse.

Danke, da ich bei meinem Problem (glücklicherweise) keine Unterverzeichnisse habe, hat die oben erwähnte einfache Lösung das gewünschte Ergebnis geliefert.

Dein Script wird aber sicher Einigen hier eine wertvolle Hilfe sein (und irgendwann auch mir, wenn ich mal das Problem habe, über mehrere Verzeichnisse ersetzen zu müssen). ;)
 
Leider gab es da noch eine weitere Komplikation.

Beträge müssen von "x,yz $" geändert werden in "$x.yz", also das Dollarzeichen vor den Betrag, das Komma durch Punkt.


Sonst wird das Ganze leider nicht korrekt eingelesen, was zu Problemen bei der statistischen Auswertung führt.

Und da bin ich mit meinen vergleichsweise rudimentären Bashkenntnissen leider hoffnungslos überfordert.
 
Hallo,

Wie ist "x,yz $" zu verstehen? Ist dies z.B.

Code:
3,70 $
also 3 dollar und 70 cents? (Komma zwischen den Zahlen)

Dann wäre folgendes vermutlich was Du suchst:

Code:
sed -i 's/\([0-9][0-9]*\),\([0-9][0-9]*\)\ *\$/\$\1.\2/g' <wo>/*
Beispiel:

Code:
abc 3,45 $ xyz
ABC 1,20$ UVW 6,20   $ XYZ
wird zu: (Punkt zwischen den Zahlen)

Code:
abc $3.45 xyz
ABC $1.20 UVW $6.20 XYZ

Gruss,
Roland
 
A

Anonymous

Gast
Systemcrasher schrieb:
Leider gab es da noch eine weitere Komplikation.
Beträge müssen von "x,yz $" geändert werden in "$x.yz", also das Dollarzeichen vor den Betrag, das Komma durch Punkt.

Kein Problem für sed aber so einfach nicht zu erklären. ;)
Code:
[robi@localhost tmp]# cat test.txt
der Listenpreis ist 123,56$
der Einkaufspreis ist 78,77$
die Steuer ist 9,99$ davon 0,88$ Mehrwertsteuer
Unkosten sind noch 0,75$
 
[robi@localhost tmp]# sed 's/\([0-9]\+\),\([0-9][0-9]\)\$/\$\1.\2/g' test.txt
der Listenpreis ist $123.56
der Einkaufspreis ist $78.77
die Steuer ist $9.99 davon $0.88 Mehrwertsteuer
Unkosten sind noch $0.75

[0-9] eine Ziffer
[0-9]\+ eine oder mehere hintereinander folgende Ziffern
\$ das Dollarzeichen
das erste was wie folgt im Suchmuster eingeschlossen ist \( \) wird an der Stelle wieder eingesetzt wo \1 steht
das zweite Vorkommen einer solchen Klammer dann dort wo \2 steht.
der Rest ist wie immer ;) ;) ;) ;)


robi
 
@RME:

Danke, hat damit prima geklappt. :) :) :)

@robi:

Vielen Dank für die ergänzende Erklärung.


Ich bin immer wieder erstaunt, wie einfach sich manche Probleme lösen lassen - wenn man weiß wie. :)
 
Oben