904 Stimmen

Wie kann ich ein rekursives Suchen/Ersetzen einer Zeichenkette mit awk oder sed durchführen?

Wie finde und ersetze ich jedes Vorkommen von:

subdomainA.example.com

mit

subdomainB.example.com

in jeder Textdatei unter dem /home/www/ Verzeichnisbaum rekursiv?

114 Stimmen

Tipp: Führen Sie die folgenden Schritte nicht in einem svn-Checkout-Baum durch... es wird die magischen .svn-Ordnerdateien überschreiben.

9 Stimmen

Oh mein Gott, das ist genau das, was ich gerade getan habe. Aber es hat funktioniert und es scheint keinen Schaden angerichtet zu haben. Was könnte schlimmstenfalls passieren?

5 Stimmen

@J.Katzwinkel: Zumindest können die Prüfsummen beschädigt werden, was wiederum Ihr Repository beschädigen kann.

3voto

Raphvanns Punkte 1419

Ein bisschen altmodisch, aber unter OS X hat es funktioniert.

Es gibt nur wenige Täuschungen:

- Bearbeitet nur Dateien mit der Endung .sls unter dem aktuellen Verzeichnis

- . muss entkommen werden, um sicherzustellen sed sie nicht als "beliebiges Zeichen" bewertet

- , wird als die sed Begrenzungszeichen anstelle des üblichen /

Beachten Sie auch, dass Sie eine Jinja-Vorlage bearbeiten müssen, um eine variable auf dem Weg eines import (aber das ist ein anderes Thema).

Vergewissern Sie sich zunächst, dass Ihr sed-Befehl das tut, was Sie wollen (damit werden nur die Änderungen auf stdout ausgegeben, die Dateien werden nicht verändert):

for file in $(find . -name *.sls -type f); do echo -e "\n$file: "; sed 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file; done

Bearbeiten Sie den sed-Befehl nach Bedarf, wenn Sie bereit sind, Änderungen vorzunehmen:

for file in $(find . -name *.sls -type f); do echo -e "\n$file: "; sed -i '' 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file; done

Beachten Sie die -i '' en el sed wollte ich keine Sicherung der Originaldateien erstellen (wie in Direktes Editieren mit sed unter OS X oder in Robert Lujos Kommentar auf dieser Seite).

Viel Spaß beim Säen, Leute!

2voto

Christoff Erasmus Punkte 877

Für Qshell (qsh) auf IBMi, nicht Bash, wie von OP angegeben.

Beschränkungen der qsh-Befehle:

  • find hat nicht die Option -print0
  • xargs hat nicht die Option -0
  • sed hat keine Option -i

Daher die Lösung in qsh:

    PATH='your/path/here'
    SEARCH=\'subdomainA.example.com\'
    REPLACE=\'subdomainB.example.com\'

    for file in $( find ${PATH} -P -type f ); do

            TEMP_FILE=${file}.${RANDOM}.temp_file

            if [ ! -e ${TEMP_FILE} ]; then
                    touch -C 819 ${TEMP_FILE}

                    sed -e 's/'$SEARCH'/'$REPLACE'/g' \
                    < ${file} > ${TEMP_FILE}

                    mv ${TEMP_FILE} ${file}
            fi
    done

Vorbehalte:

  • Lösung schließt Fehlerbehandlung aus
  • Nicht Bash wie von OP getaggt

2voto

tgunr Punkte 1517

Ich benutze nur Oberteile:

find . -name '*.[c|cc|cp|cpp|m|mm|h]' -print0 |  xargs -0 tops -verbose  replace "verify_noerr(<b args>)" with "__Verify_noErr(<args>)" \
replace "check(<b args>)" with "__Check(<args>)"

2voto

Pawel Punkte 399

Durch die Kombination von grep y sed

for pp in $(grep -Rl looking_for_string)
do
    sed -i 's/looking_for_string/something_other/g' "${pp}"
done

2voto

Stenemo Punkte 585

Um mehrere Dateien zu ändern (und ein Backup als *.bak ) :

perl -p -i -e "s/\|/x/g" *

nimmt alle Dateien im Verzeichnis und ersetzt | mit x genannt "Perl-Kuchen" (kinderleicht)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X