Wie finde und ersetze ich jedes Vorkommen von:
subdomainA.example.com
mit
subdomainB.example.com
in jeder Textdatei unter dem /home/www/
Verzeichnisbaum rekursiv?
Wie finde und ersetze ich jedes Vorkommen von:
subdomainA.example.com
mit
subdomainB.example.com
in jeder Textdatei unter dem /home/www/
Verzeichnisbaum rekursiv?
Ersetzen von find(1)
mit dem einfacheren fd(1)
/ fdfind
= https://github.com/sharkdp/fd :
fdfind . --type f --exec sed -i "s/original_string/new_string/g"
Adressierung fd(1)
iconsistent pkg & cmd Namen
Ich mache eine alias fdfind='fd'
auf macOS für eine einheitliche cmd-Benennung (zwischen meinen macOS- und Linux-Plattformen).
Mehr zu diesem Thema unter https://github.com/sharkdp/fd/issues/1009 .
Weitere Details und zusätzliche Funktionen
# bash examples:
1='original_string'
2='new______string'
# for this (the original-poster's) question:
1='subdomainA.example.com'
2='subdomainB.example.com'
# 'fdfind' (on at least Ubuntu 20.04) = 'fd' = https://github.com/sharkdp/fd
fdfind . --type f --exec sed -i "s/$1/$2/g"
# Here's a slightly-more-complex example that
# a. excludes (-E) .git/ and archive/ dirs, and
# b. performs a word-boundary search on the original_string (\<$1\>):
fdfind . -E .git/ -E archive/ --type f --exec sed -i "s/\<$1\>/$2/g"
Noch ausgefallener: die Kontrolle der Wortgrenzen vom dritten ( $3
) Befehlszeilen-Parameter (dritter Parameter = noword
bedeutet keine Begrenzung, leftword
bedeutet nur linksseitige Wortgrenze, rightword
bedeutet nur rechtsseitige Begrenzung):
#!/usr/bin/env bash
#
# replace-tree.bash
#
# 'fdfind' (on at least Ubuntu 20.04) = 'fd' = https://github.com/sharkdp/fd
if [ $# -lt 2 ]; then
echo "$0: Please provide at least 2 arguments."
exit 1
fi
original="\<$1\>"
if [ "$3" = "noword" ]; then
original="$1"
elif [ "$3" = "leftword" ]; then
original="\<$1"
elif [ "$3" = "rightword" ]; then
original="$1\>"
fi
fdfind . --type f --exec sed -i "s/$original/$2/g"
Beispiel für die Verwendung:
$ replace-tree.bash original_string new_string leftword
$
So ersetzen Sie alle übereinstimmenden Inhalte string_1 con string_2 von allen .c y .h Dateien im aktuellen Verzeichnis und in den Unterverzeichnissen (außer .git/) .
Dies funktioniert bei Mac :
find . -type f -path "*.git*" -prune -o -name '*\.[ch]' -exec \
sed -i '' -e 's/'$1'/'$2'/g' {} +
Dies sollte funktionieren bei Linux (Wurde noch nicht getestet):
find . -type f -path "*.git*" -prune -o -name '*\.[ch]' -exec \
sed -i 's/string_1/string_2/g' {} +
Dies ist die beste Allround-Lösung, die ich für OSX und Windows (msys2) gefunden habe. Sollte mit allem funktionieren, das die gnu-Version von sed nutzen kann. Überspringt die .git-Verzeichnisse, so dass es nicht Ihre Prüfsummen beschädigt.
Auf dem Mac installieren Sie zuerst coreutils und stellen Sie sicher, dass gsed im Pfad enthalten ist -
brew install coreutils
Dann füge ich diese Funktion in meine zshrc/bashrc ein ->
replace-recursive() {
hash gsed 2>/dev/null && local SED_CMD="gsed" || SED_CMD="sed"
find . -type f -name "*.*" -not -path "*/.git/*" -print0 | xargs -0 $SED_CMD -i "s/$1/$2/g"
}
usage: replace-recursive <find> <replace>
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.
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.
4 Stimmen
Kleiner Tipp für alle, die sed verwenden: Es fügt Zeilenumbrüche an Ihre Dateien an. Wenn Sie das nicht wollen, machen Sie zuerst ein find-replace, das mit nichts übereinstimmt, und übergeben Sie das an Git. Dann führen Sie die echte Ersetzung durch. Dann rebase interaktiv und lösche das erste.
0 Stimmen
@funroll Oder verwenden Sie ein Werkzeug, das das Hinzufügen von Zeilenumbrüchen nicht erzwingt, wie z.B. Perl, oder akzeptieren Sie die Tatsache, dass POSIX strikt vorschreibt, dass Textdateien Zeilenabschlüsse haben müssen.
6 Stimmen
Sie können ein Verzeichnis, wie z. B. git, von den Ergebnissen ausschließen, indem Sie
-path ./.git -prune -o
においてfind . -path ./.git -prune -o -type f -name '*matchThisText*' -print0
vor der Übergabe an xargs0 Stimmen
Diese Antwort auf der Unix-Website StackExchange ist ebenfalls sehr interessant: unix.stackexchange.com/a/112024/354626
0 Stimmen
Alternative Lösung von SuperUser Wie kann ich eine rekursive Suche und Ersetzung über die Befehlszeile durchführen? :
find . -type f \( -iname \*.ht* -o -iname \*.php \) -exec sed -i'' -e 's/findString/replString/g' {} +
(Zeichenketten müssen escaped werden, z.B. Punkte wie\.
) Ignoriert möglicherweise Dateinamen mit Leerzeichen(?)