ubuntuusers.de

Ordner und Unterordner rekursiv nach String durchsuchen und ersetzen?

Status: Ungelöst | Ubuntu-Version: Ubuntu 16.04 (Xenial Xerus)
Antworten |

DrMandela

Anmeldungsdatum:
2. März 2017

Beiträge: 8

Ich versuche verzweifelt alle Dateien in einem Ordner (Unterordner eingeschlossen) nach einem String zu durchsuchen und diese durch einen neuen String zu ersetzen. Leider ohne Erfolg.

1
sed 's/'SUCHEN'/'ERSETZEN'/g' *

Da ich damit ein Wordpress Projekt behandeln möchte, kommt hierbei diese Fehlermeldung:

1
sed: Lesefehler in wp-admin: Ist ein Verzeichnis

Ich verstehe nicht warum er nicht in den Ordnern weitersucht und das ersetzen fortsetzt.

sebix Team-Icon

Moderator, Webteam

Anmeldungsdatum:
14. April 2009

Beiträge: 5582

EDIT: Ist falsch, siehe nachfolgender Post.

Weil du es anders befohlen hast. Deine Eingabe kann man auch wie folgt darstellen:

1
sed 's/' SUCHEN '/' ERSETZEN '/g' *

Da du fuer suchen vermutlich wp-admin genomen hast, fuehrt sed den Befehl 's/' nur auf den Ordner wp-admin aus, den es nicht gibt. Also richtig Quoten:

1
sed 's/SUCHEN/ERSETZEN/g' *

Wenn / oder ' in den Zeichenketten vorkommen, einfach escapen.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4676

Wohnort: Berlin

@sebix: Die Erklärung ist falsch und damit ist die Lösung keine. Ob zwischen sed 's/'SUCHEN'/'ERSETZEN'/g' * und sed 's/SUCHEN/ERSETZEN/g' * ein Unterschied besteht kommt einzig und alleine auf die tatsächlichen Werte von SUCHEN und ERSETZEN an. Wenn die beispielsweise tatsächlich so heissen, dann besteht zwischen den beiden kein Unterschied. Insbesondere wird das Argument 's/'SUCHEN'/'ERSETZEN'/g' nicht grundsätzlich auf fünf Argumente aufgeteilt als wären da Leerzeichen dazwischen.

Das Problem ist das das Muster * a) nicht nur zu Dateinamen sondern auch Verzeichnisnamen expandiert wird, und das b) sed mit Verzeichnisnamen an der Stelle so nichts anfangen kann und schon gar nicht auf die Idee kommt rekursiv einfach alles zu verarbeiten. Fänd ich persönlich auch ziemlich gefährlich wenn das so wäre, weil man sich damit viel zu leicht extrem in den Fuss schiessen könnte.

@DrMandela: Du musst entweder alle Dateinamen angeben die verarbeitet werden sollen, oder Du musst sed für alle Dateinamen aufrufen. Dazu könntest Du Dir beispielsweise find und dessen Möglichkeiten anschauen nach Dateien zu suchen und Verzeichnisse auszuschliessen und etwas pro Datei auszuführen oder auch für mehr als eine Datei auf einmal etwas auszuführen falls das effizienter ist.

sebix Team-Icon

Moderator, Webteam

Anmeldungsdatum:
14. April 2009

Beiträge: 5582

Marc_BlackJack_Rintsch schrieb:

Insbesondere wird das Argument 's/'SUCHEN'/'ERSETZEN'/g' nicht grundsätzlich auf fünf Argumente aufgeteilt als wären da Leerzeichen dazwischen.

Duh, hab ich falsch angenommen. Danke fuer die Korrektur.

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

DrMandela schrieb:

1
sed 's/'SUCHEN'/'ERSETZEN'/g' *

...
Ich verstehe nicht warum er nicht in den Ordnern weitersucht und das ersetzen fortsetzt.

  1. liest sed einfach nur die Dateien, so wie sie ihm angereicht werden. Was ihm da konkret angereicht wird, kannst Du Dir ja mal angucken mit so einer Befehlsschleife:

    1
    for f in * ; do echo "$f"; done
    
  2. Hast Du da eine wilde Form von Cargo-'Quoting' - ist Dir eigentlich klar, dass ausgerechnet Dein SUCHEN und ERSETZEN außerhalb des 'Quoting' stehen ?
    → Solltest Du unbedingt noch einmal nachlesen !

Wenn Du tatsächlich einen ganzen Verzeichnisbaum absuchen willst, dann brauchst Du dafür find . → im Wiki nachlesen !
Da kannst Du dann Dein exec sed -i 's/SUCHEN/ERSETZEN/g' {} \; anhängen. (ich glaube, so hattest Du es eigentlich gewollt, nichtwahr ?)

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

track schrieb:

Wenn Du tatsächlich einen ganzen Verzeichnisbaum absuchen willst, dann brauchst Du dafür find . → im Wiki nachlesen !
Da kannst Du dann Dein exec sed -i 's/SUCHEN/ERSETZEN/g' {} \; anhängen. (ich glaube, so hattest Du es eigentlich gewollt, nichtwahr ?)

Das sähe dann so aus:

1
find dir -type f exec sed -i 's/SUCHEN/ERSETZEN/g' {} +

Das würde ich erst mal in einem Testordner testen, weil die mögliche Zerstörungskraft recht hoch ist.

misterunknown Team-Icon

Ehemalige
Avatar von misterunknown

Anmeldungsdatum:
28. Oktober 2009

Beiträge: 4403

Wohnort: Sachsen

rklm schrieb:

1
find dir -type f exec sed -i 's/SUCHEN/ERSETZEN/g' {} +
find dir -type f -exec sed -i 's/SUCHEN/ERSETZEN/g' {} +

BillMaier Team-Icon

Supporter

Anmeldungsdatum:
4. Dezember 2008

Beiträge: 6494

wieso nun + ? Eine Zeile mit find und exec endet doch mit \;

find dir -type f -exec sed -i 's/SUCHEN/ERSETZEN/g' {} \;

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

BillMaier schrieb:

wieso nun + ?

Das übergibt gleich die ganze Liste an gefundenen Dateien an sed (→ vgl im Wiki)
Robert liebt diese Variante, weil sie im Prinzip ein µy-chen schneller ist.

Eine Zeile mit find und exec endet doch mit \;

All die -exec usw. können grundsätzlich für Einzel-Funde oder die gesammelte Liste ausgeführt werden, je nachdem.
Mir (und manchem Anderen, nehme ich an) ist es zu kompliziert, jedes Mal zu überlegen, ob der konkrete Befehl sinnvoll mit der gesammelte Liste funktioniert. Daher siehst Du so oft, praktisch "immer" das "\;" am Ende. (das µy-chen schneller hin oder her: egal)

LG,

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

track schrieb:

BillMaier schrieb:

wieso nun + ?

Das übergibt gleich die ganze Liste an gefundenen Dateien an sed (→ vgl im Wiki)
Robert liebt diese Variante, weil sie im Prinzip ein µy-chen schneller ist.

... und einem das Eingeben eines Backslashes und Semikolons erspart. Ein "+" tippt sich deutlich eleganter.

Eine Zeile mit find und exec endet doch mit \;

All die -exec usw. können grundsätzlich für Einzel-Funde oder die gesammelte Liste ausgeführt werden, je nachdem.
Mir (und manchem Anderen, nehme ich an) ist es zu kompliziert, jedes Mal zu überlegen, ob der konkrete Befehl sinnvoll mit der gesammelte Liste funktioniert. Daher siehst Du so oft, praktisch "immer" das "\;" am Ende. (das µy-chen schneller hin oder her: egal)

Echt, das findest Du kompliziert zu überlegen? Staun. Seit cp und mv die Option -t haben gibt es doch fast keinen Befehl mehr, der nicht mehrere Dateien gleichartig verarbeiten kann. Und wenn, dann weiß man das doch - man muss doch sowieso wissen, was der Befehl tut.

Ciao

robert

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13176

PS: Ich habe gerade so einen Fall, wo die Version mit "+" deutlich schneller ist: find ... -exec svn revert {} + ist extrem viel schneller als find ... -exec svn revert {} \;. Ich nehme an, das liegt an der Kommunikation mit dem SVN-Server, die ja aufgebaut und authentifiziert werden muss.

BillMaier Team-Icon

Supporter

Anmeldungsdatum:
4. Dezember 2008

Beiträge: 6494

rklm schrieb:

Ein "+" tippt sich deutlich eleganter.

Nicht auf ner US-Tastatur 😀

Aber genug OffTopic.

@DrMandela ist ja doch schon ne Weile her jetzt. Thema gelöst?

Bearbeitet von sebix:

Userlink korrigiert.

Antworten |