PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Text ersetzen in mehreren Dateien und Ordnern, sed



knallzapzerap
18.12.04, 18:22
Ich habe einen Ordner, indem einige Dateien und auch Unterordner vorhanden sind, indem auch wieder Dateien sind. Nun muss ich in all diesen Dateien ein bestimmtes Wort (z.B. subSilver) durch ein anderes (z.B. knall) ersetzen. Dieses Wort kann mehrmals oder auch nur einmal in jeder Datei vorkommen oder auch in einigen Dateien nicht vorhanden sein. Ich möchte, wenn möglich, nicht jede Datei einzeln bearbeiten, sondern alle auf einen Schlag. Die Suche hier im Forum, brachte mich zu dem Befehl sed. Da ich kaum Englisch kann, bin ich hauptsächlich auf deutsche Docus angewiesen. Nach dem lesen von http://www.linuxfibel.de/sed.htm hänge ich nun leider fest.
Meine Idee war um subSilver in knall zu ersetzen folgendes, hatte aber nicht den gewünschten Erfolg:
sed -n 's#subSilver#knall#gp' *
oder auch
sed -n 's/subSilver/knall/gp' *

Wie bekomme ich es hin, alle in dem Ordner und dessen Unterordnern enthaltenen Dateien so zu bearbeiten, das subSilver durch knall ersetzt wird?

Freekazonid
18.12.04, 18:26
find . -type f -name pe -exec sed -i -e 's/^.*WORD1.*$/WORD2/' {} \;


pe ist der name der dateien wo das ersetzen stattfindet, WORD1 ist das urspruengliche wort, WORD2 das was an seiner stelle hinkommt. der rest alles immer so alles

knallzapzerap
18.12.04, 20:57
haut leider nicht hin :(
Mein erster Versuch war
find . -type f -name * -exec sed -i -e 's/^.*subSilver.*$/knall/' {} \;
Da er den Platzhalter leider nicht aktzeptierte, versuchte ich es mit einer einzelnen Datei, wobei ich ja eigentlich den ganzen Ordner und die Unterordner in einem Schlag bearbeiten wollte.
find . -type f -name theme_info.cfg -exec sed -i -e 's/^.*subSilver.*$/knall/' {} \;
Daraufhin änderte er die Datei wie folgt:
Aus


<?php
//
// phpBB 2.x auto-generated theme config file for subSilver
// Do not change anything in this file!
//
$subSilver[0]['template_name'] = "subSilver";
$subSilver[0]['style_name'] = "subSilver";
$subSilver[0]['head_stylesheet'] = "subSilver.css";
$subSilver[0]['body_background'] = "";
.....
?>


wurde



<?php
//
knall
// Do not change anything in this file!
//
knall
knall
knall
knall
.....
?>

tictactux
18.12.04, 21:43
haut leider nicht hin :(
Mein erster Versuch war
find . -type f -name * -exec sed -i -e 's/^.*subSilver.*$/knall/' {} \;
Da er den Platzhalter leider nicht aktzeptierte, versuchte ich es mit einer einzelnen Datei, wobei ich ja eigentlich den ganzen Ordner und die Unterordner in einem Schlag bearbeiten wollte.
find . -type f -name theme_info.cfg -exec sed -i -e 's/^.*subSilver.*$/knall/' {} \;

1. denke über Shell-Expansion nach. "-name *" kann nicht hinhaun, da das
* von der Shell expandiert wird, und find stolpert darüber mit Syntaxfehlern.
Abilfe: -name '*' (oder "*").

2. reguläre Ausdrücke sind keine Shell-Muster.
"^.*subSilver" findet das gleiche wie "^.*sonstWas" (ein als greediness bzw.
"Gierigkeit" bezeichnetes Verhalten).
Das Verankern mit ^ und $ macht für mich in diesem Ausdruck keinen Sinn,
da Du ja wortweise arbeiten willst (?)
Begrenzer für Wortgrenzen sind \< und \>.
also z.B. sed -e 's/\<subSilver\>/knall/g'

3. es kann übersichtlicher sein, den sed-Aufruf in eine Schleife zu packen:

#!/bin/bash
DATMASKE='*.php'
for x in $(find . -type f -iname "$DATMASKE"); do
sed -i -e 's/\<subSilver\>/knall/g' $x
done

HTH
Wolfgang

knallzapzerap
18.12.04, 23:38
Das Verankern mit ^ und $ macht für mich in diesem Ausdruck keinen Sinn,
da Du ja wortweise arbeiten willst (?)


Ich möchte das jedes subSilver, was in den ganzen Dateien vorkommt in knall umbenannt wird, ansonsten aber keinerlei Änderungen stattfinden. Das ganze handelt sich um verschiedene Styles, die je nach Ihrem Stylename, in allen Dateien abgeglichen werden müssen. Der Weg über ein script ist natürlich wesentlich kompfortabler, da ich dann nur jedesmal wenn ein neuer Style erstellt wird, den neuen Stylenamen im Script abändern brauche.



3. es kann übersichtlicher sein, den sed-Aufruf in eine Schleife zu packen:

#!/bin/bash
DATMASKE='*.php'
for x in $(find . -type f -iname "$DATMASKE"); do
sed -i -e 's/\<subSilver\>/knall/g' $x
done



bevor ich nun das ganze nocheinmal ausprobiere 2 Verständnissfragen.
DATMASKE='*.php' würde alle Dateien mit der Endung .php im aktuellen Ordner bearbeiten?
Da ich 2 Dateitypen habe (tpl und cfg) müsste ich mir 2 Scripte schreiben, wo einmal '*.tpl' und einmal '*.cfg' als DATMASKE=stehen würden und diese in allen Ordnern jeweils einmal ausführen?


EDIT
habe jetzt mal mit oben genanntem Code mit der Änderung
DATMASKE='*.cfg'
versucht die Dateien zu ändern und erhalte folgende Fehlermeldung
zap@knall:~/phpbb/phpbb/templates/knall> ./subSilver-knall-cfg.sh
: bad interpreter: Datei oder Verzeichnis nicht gefunden

tictactux
18.12.04, 23:49
Ich möchte das jedes subSilver, was in den ganzen Dateien vorkommt in knall umbenannt wird, ansonsten aber keinerlei Änderungen stattfinden.
Tut das genannte Beispiel auch. sed arbeitet die Datei Zeile für Zeile durch (->man sed).
Das Flag /g weist sed zusätzlich an, auch mehrere Vorkommen innerhalb
einer Zeile zu ersetzen.

DATMASKE='*.php' würde alle Dateien mit der Endung .php im aktuellen Ordner bearbeiten?
Die Maske ist ein Beispiel. Es würden alle Dateien im und unterhalb des aktuellen
Ordners bearbeitet. Das ist der Sinn des Einsatzes von find(1).

Da ich 2 Dateitypen habe (tpl und cfg) müsste ich mir 2 Scripte schreiben, wo einmal '*.tpl' und einmal '*.cfg' als DATMASKE=stehen würden und diese in allen Ordnern jeweils einmal ausführen?
Nein, find hat eine "oder" Option (-o). Der Aufruf könnte aussehen:
$(find . -type f -iname "*.tpl" -o -iname "*.cfg")

Gruss,
Wolfgang

tictactux
18.12.04, 23:57
Zu Deinem "bad Interpreter": Prüfe die erste Zeile in dem Skript.
Der Name der Shell hinter #! ist falsch geschrieben oder das Verzeichnis
stimmt nicht.

btw: Zum Testen solltest Du natürlich nicht auf Original-Dateien arbeiten.
Hilfreich ist vielleicht, die Option -i von sed abzuändern in --in-place=bak
oder "-ibak", wodurch Backups von den bearbeiteten Originaldateien erstellt
werden (mit der oben angegebenen Erweiterung)

knallzapzerap
19.12.04, 00:05
ich habe das Script jetzt so geschrieben und ausführbar gemacht.


#!/bin/bash
for x in $(find . -type f -iname "*.tpl" -o -iname "*.cfg"); do
sed -i -e 's/\<subSilver\>/knall/g' $x
done


Leider habe ich immer noch den bad interpreter Fehler.
#!/bin/bash habe ich auch in anderen Scripten die diese Fehlermeldung nicht haben.

Edit
eine Sicherungskopie der Dateien habe ich selbstverständlich vorher erstellt :)

tictactux
19.12.04, 00:15
ich habe das Script jetzt so geschrieben und ausführbar gemacht.
Wenn Du da absolut sicher bist, und überprüft ob /bin/bash existiert
(sollte auf Linux ohnehin sein :) ), prüfe, ob Du das Skript von einer
Partition startest (z.B. FAT32) die kein exec-Attribut hat (bzw. mit user(s)
oder noexec gemountet ist).
In dem Fall, kopiere das Skript am besten nach /usr/local/bin.

knallzapzerap
19.12.04, 00:27
es ist wie verhext
/bin/bash ist trotz SuSE vorhanden ;)

/dev/hda7 /home reiserfs defaults 1 2
/dev/hda8 /usr reiserfs defaults 1 2

chmod 777 habe ich ausgeführt, die Daten habe ich herauskopiert aus dem Script und daher schliesse ich einen Flüchtigkeitsrechtschreibfehler aus.
Es funktioniert nicht wenn das script im Datenverzeichnis ist und auch nicht im /usr/local/bin Immer wieder der bad interpreter. Als das Script im /usr/local/bin war habe ich natürlich den ./ weggelassen und vorher das Script im Datenverzeichnis gelöscht

tictactux
19.12.04, 00:45
/bin/bash ist trotz SuSE vorhanden ;)
Daher der Begriff "SuSE-bashing" :D

Kopier doch mal ein Skript, welches sonst funktioniert in das Verzeichnis,
in dem Du Dich befindest. Hat das Verzeichnis vielleicht keine Ausführrechte ?
(obwohl die Fehlermeldung dann anders lauten sollte...)

knallzapzerap
19.12.04, 00:53
Ein anderes Script in dem Ordner funktioniert problemlos.
Das Verzeichniss hat 755

tictactux
19.12.04, 00:58
Sorry, dann muß es an der ersten Zeile liegen, mehr fällt mir dazu nicht ein.
Achte darauf, daß es wirklich die erste Zeile ist (keine Leerzeilen davor).
Teste es ansonsten mit: sh DeinScript

knallzapzerap
19.12.04, 01:06
ich hab den Fehler gefunden :rolleyes:
Es lag an kwrite, der bei mir gerade als Editor ausgedient hat. Ich habe die Datei mit mcedit aufgerufen und sah dort in kwrite unsichtbare ^M nach jedem Zeilenende, die wohl durch kwrite dort aus mir unerfindlichen Gründen eingefügt wurden. Als ich diese entfernt habe funktionierte das Script :)

Vielen Dank für die Hilfe, mit diesem Script ist mir in nächster Zeit einiges an Arbeit abgenommen :) allerdings muss ich mir jetzt einen anderen Editor suchen, aber da ist die Auswahl ja doch etwas grösser ;)

tictactux
19.12.04, 01:34
Es lag an kwrite, der bei mir gerade als Editor ausgedient hat. Ich habe die Datei mit mcedit aufgerufen und sah dort in kwrite unsichtbare ^M nach jedem Zeilenende, die wohl durch kwrite dort aus mir unerfindlichen Gründen eingefügt wurden. Als ich diese entfernt habe funktionierte das Script :) Ich gratuliere mir dazu, darauf nicht spontan geantwortet zu haben :D

allerdings muss ich mir jetzt einen anderen Editor suchen
Keinen anderen, nur einen Editor.
Viel Spaß dabei,
Wolfgang

knallzapzerap
19.12.04, 02:16
Ich gratuliere ebenfalls :ugly:

Nun stellt sich mir natürlich die Frage welcher Editor den Namen Editor auch verdient :cool:
Ich habe mir nun kate, emacs und kvim angeguckt, wobei kate mir da auf Anhieb am besten gefällt. In Emacs, vim bzw kvim benötige ich wohl eine höhere Einarbeitungszeit :eek: Da ich den Editor eigentlich nur für kleinere Shellscripte, html und php Bearbeitung benötige, überlege ich nun ob kate dafür nicht ausreicht. Wichtig ist, das ich im kde mit markieren und Paste über die mittlere Maustaste arbeiten kann, was bei mir zb im mcedit nicht funktioniert. Über einen Tip würde ich mich freuen :D

tictactux
19.12.04, 02:58
Ich habe mir nun kate, emacs und kvim angeguckt, wobei kate mir da auf Anhieb am besten gefällt. In Emacs, vim bzw kvim benötige ich
wohl eine höhere Einarbeitungszeit :eek: Da ich den Editor eigentlich nur für kleinere Shellscripte, html und php Bearbeitung benötige, überlege ich nun ob kate dafür nicht ausreicht. Wichtig ist, das ich im kde mit markieren und Paste über die mittlere Maustaste arbeiten kann, was bei mir zb im mcedit nicht funktioniert. Über einen Tip würde ich mich freuen :D
Ich benutze vi(m). Eine Entscheidung die zu einem Zeitpunkt gefallen ist,
als es Linux noch nicht gab und Emacs mehr Speicher brauchte als manches
Betriebssystem ;)
Was Einarbeitungszeit angeht: ja, die gibt es - und nicht zu knapp.
Frag Dich also, wie lange/oft und auf welchen Betriebssystemen Du den Editor
benötigst, und ob er mächtig genug sein soll, auch komplexere Dinge zu
bewältigen, ob er in Deine Arbeitsumgebung/IDE integrierbar ist/sein soll,
ob Du ihn auch noch in 5 Jahren benutzen willst, e.t.c.

Gruss,
Wolfgang

Spiff
19.12.04, 10:08
Wichtig ist, das ich im kde mit markieren und Paste über die mittlere Maustaste arbeiten kann, was bei mir zb im mcedit nicht funktioniert.

Du musst bei solchen Mausaktionen die Shift-Taste drücken.
Dann klappt's auch mit dem Einfügen :)

knallzapzerap
19.12.04, 11:28
Die Entscheidung ist gefallen :D

Ich werde mich jetzt wirklich mal hinsetzen und mich mit vim beschäftigen. Das es wohl der beste Editor ist, aber eben recht umständlich in der Handhabung war mir ja schon lange klar ;)

Nebenbei werde ich aber sicherlich noch mcedit nutzen, der durch den Tip mit der Shifttaste bei mir doch wieder ein recht schnelles arbeiten ermöglicht :)

Öfters werde ich mich sicherlich noch dabei erwischen, kate zu nutzen, da er für mich die gewohnteste Arbeitsumgebung darstellt, aber wenn ich gerade Zeit habe sicherlich dann auf die anderen beiden zurückgreifen, bis ich diese soweit beherrsche, das ich evtl besser beurteilen kann, was für mich dann am besten geeignet ist :D

Vielen Dank nochmals für die Hilfe, das ganze hat mir ziemlich viel Zeit erspart, die ich nutzen werde, um andere Dinge, wie zb den vim zu erlernen :)