Bash um Text zu ändern in Dateien

Bububoomt

ohne Vertrauen
ID: 10361
L
28 April 2006
19.666
769
Habe folgendes gefunden, aber wie muss ich die strings angeben, wenn dort wiederum " vorhanden sind? Gibt es noch andere Zeichen auf die ich aufpassen muß? Z.B. Fragezeichen?

Code:
#!/bin/bash
OLD="Suchen"
NEW="Ersetzen"
DPATH="/"
BPATH="/tools/backup/
TFILE="/tmp/out.tmp.$$"
[ ! -d $BPATH ] && mkdir -p $BPATH || :
for f in $DPATH
do
  if [ -f $f -a -r $f ]; then
    /bin/cp -f $f $BPATH
   sed "s/$OLD/$NEW/g" "$f" > $TFILE && mv $TFILE "$f"
  else
   echo "Error: Cannot read $f"
  fi
done
/bin/rm $TFILE
 
Wenn die gesuchte Zeichenkette Sonderzeichen enthält muß ihnen jeweils (mindestens) ein "\" vorangestellt werden. Betroffen sind alle Zeichen, die irgendwo eine besondere Funktion haben (ohne Anspruch auf Vollständigkeit):

reguläre Ausdrücke: ^.*+?()[]{}&
Steuerzeichen: \a\f\n\t\r
Shell: #<>()[] |^!"'`$&?\;:- (Achtung: Leerzeichen !! )

Außerdem gibt es ein Reihe implementationsabhängiger Sonderzeichen und/oder Zeichenfolgen, die zB im Ersatztext verwendet werden können um Dateinamen, Zeilennummern, Zeitstempel oÄ einzusetzen. "man sed" bzw. "info sed" sollte da weiterhelfen.

Der Aufruf "sed -i.bak -e s/Suchtext/Ersatztext/ Dateiname(n)" legt für jede bearbeitete Datei im jeweiligen Verzeichnis eine Sicherungskopie mit dem Suffix ".bak" an (kein Leerzeichen zwischen "-i" und dem gewünschten Suffix!). Man kann sich damit das fehlerträchtige Hantieren mit temporären Kopien in anderen Verzeichnissen sparen. Wird kein Suffix angegeben wird die Datei durch die neue Version ersetzt.

Beispiel (vor allen Links einen Zeilenumbruch einfügen):

Code:
[FONT="Courier New"]sed -i.org -e s/\<a\ /\\\n\&/g index.html[/FONT]

ist äquivalent zu

Code:
[FONT="Courier New"]cp index.html index.html.org
sed -e s/\<a\ /\\\n\&/g index.html.org > index.html[/FONT]

Ohne Backup (bei komplexeren Ausdrücken aber nur zu empfehlen wenn man weiß WAS man macht und WOMIT man es macht)
Code:
[FONT="Courier New"]sed -i -e s/\<a\ /\\\n\&/g index.html[/FONT]
 
Wäre doch sicherlich möglich, dass ich den text in ne Datei schreibe, so dass ich das auslese in der batch und so dann den String direkt ohne zu ändern einbauen kann in die datei oder?
Beim Einlesen wird dann halt escasped? So würde ichs in C# und co machen...
 
Anstatt die Ausdrücke bei jedem Aufruf auf der Kommandozeile wieder neu zu tipseln (und neue Fehler zu erfinden...) kannst Du die Paare Suchtext/Ersatztext in einer separaten Datei (*) zusammenstellen. Der Aufruf für obiges Beispiel sieht dann so aus:
Code:
sed -i.org -f sed.cmd index.html
Die Steuerdatei sed.cmd
Code:
# Zeilenumbruch vor Links einfügen
s/<a /\n&/g


(*) Ein Paar pro Zeile, Format: s/dieseZeichenketteSuchen/DurchEinenAnderenTextErsetzen/. Leerzeilen sind zulässig, Kommentare beginnen mit "#" und erstrecken sich bis zum Zeilenende. Um die Suche nicht nach dem ersten Treffer zu beenden sondern alle Vorkommen bis zum Zeilenende zu ersetzen muß ein "g" (global) angehängt werden. Achtung: unterschiedliche Anzahl an "\" in der Steuerdatei und auf der Kommandozeile, die Ausdrücke einfach per Copy/Paste zu übernehmen produziert gelegentlich seltsame Ergebnisse.