So ersetzen Sie eine Zeichenfolge in mehreren Dateien in der Linux-Befehlszeile

461

Ich muss eine Zeichenfolge in vielen Dateien in einem Ordner ersetzen und nur sshauf den Server zugreifen. Wie kann ich das machen?

mridul4c
quelle

Antworten:

602
cd /path/to/your/folder
sed -i 's/foo/bar/g' *

Vorkommen von "foo" werden durch "bar" ersetzt.

Auf BSD-Systemen wie macOS müssen Sie eine Sicherungserweiterung wie -i '.bak'"Risikobeschädigung oder Teilinhalt" pro Manpage bereitstellen .

cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *
kev
quelle
13
Dies scheint für mich nicht zu funktionieren, wenn die Zeichenfolge Leerzeichen oder Sonderzeichen enthält. Irgendeine Idee, warum das so sein könnte, oder muss ich ihnen irgendwie entkommen? Vielen Dank!
Matthew Herbst
13
Zumindest für meine Version sed, -ierfordert eine Zeichenfolge , nachdem es, die zu den alten Dateinamen angehängt wird. So sed -i .bak 's/foo/bar/g' *.xxverschiebt alle .xxDateien auf den .xx.bakErsatznamen und erzeugt dann die .xxDateien mit den foo → bar Substitution.
Anaphory
24
Wenn jemand nach mehr Optionen suchen möchte, gibt es eine Antwort auf Unix-Stack-Austausch, die mehr Anwendungsfälle abdeckt.
Reddy
19
@MatthewHerbst, um Leerzeichen zu entkommen, verwenden Sie \ like sed -i 's/foo\ with\ spaces/bar/g' *. Ich nehme an, Sie haben es nach so langer Zeit herausgefunden ... aber auf diese Weise bleibt es für andere, die das gleiche Problem finden.
Manuelvigarcia
5
Für etwas Rekursives können Sie Folgendes versuchen. Beachten Sie, dass es nicht funktioniert, wenn die Liste der Dateien sehr groß ist. sed -i -e 's/foo/bar/g' $(find /home/user/base/dir)
Scot
243

Ähnlich wie bei Kaspar, jedoch mit dem g-Flag, um alle Vorkommen in einer Zeile zu ersetzen.

find ./ -type f -exec sed -i 's/string1/string2/g' {} \;

Für globale Groß- und Kleinschreibung nicht:

find ./ -type f -exec sed -i 's/string1/string2/gI' {} \;
Céline Aussourd
quelle
23
Wenn Sie unter OSX arbeiten und Ihre Muster möglicherweise Punkte enthalten und eine LC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' {} \;
Jonathan H,
2
Dies hat definitiv für mich funktioniert, da es das Filtern mit -name "* .js" '
Marcello de Sales
1
Eine ausführliche Option wäre cool, aber Sie können einfach erneut prüfen, ob die Änderungen vorgenommen wurden. Hinweis: Für Platzhalter versuchen Sie '-name "* .php"' und grep ist schlecht mit Rekursion und Platzhaltern, Sie müssen --include=*.whatevermit -r
PJ Brunet
12
Tun Sie dies nicht aus dem Stammverzeichnis eines ausgecheckten Git-Repos. Sie könnten versehentlich die Datenbank in beschädigen .git/. Stellen Sie sicher, dass cdSie auf eine niedrigere Ebene gehen.
Erikprice
1
Ich habe das gerade in meinem Git Repo gemacht und git statuskehre jetzt zurück : error: bad index file sha1 signature.... fatal: index file corrupt. Was gibt?
Jin
165

Die Antwort von @ kev ist gut, wirkt sich jedoch nur auf Dateien im unmittelbaren Verzeichnis aus. Im folgenden Beispiel wird grep verwendet, um Dateien rekursiv zu finden. Es funktioniert immer für mich.

grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @

Befehlsaufschlüsselung

grep -r : --rekursiv , rekursiv alle Dateien unter jedem Verzeichnis lesen.
grep -l : --print-with-Matches , druckt den Namen jeder übereinstimmenden Datei, anstatt übereinstimmende Zeilen zu drucken.
grep -i : --ignore-case .

xargs : transformiere die STDIN in Argumente, folge dieser Antwort .
Der Befehl xargs -i @ ~ enthält @ ~ : einen Platzhalter für das Argument, das an einer bestimmten Position im Befehl ~ verwendet werden soll ~ . Das Zeichen @ ist ein Platzhalter, der durch eine beliebige Zeichenfolge ersetzt werden kann.

sed -i : Bearbeiten Sie vorhandene Dateien ohne Backups.
sed s / regexp / replace / : Ersetzt die Zeichenfolge, die mit regexp übereinstimmt, durch Ersatz .
sed s / regexp / replace / g : global , ersetzen Sie jedes Spiel anstelle nur des ersten Spiels.

Pymarco
quelle
13
Das hat bei mir nicht funktioniert, aber das hat funktioniert:grep --include={*.php,*.html,*.js} -rnl './' -e "old-word" | xargs -i@ sed -i 's/old-word/new-word/g' @
Dennis
7
@pymarco Kannst du diesen Befehl bitte erklären? Ich weiß nicht, warum Sie xargs verwenden mussten, anstatt nur sed zu verwenden |, auch warum -iim Befehl xargs? Ich habe im Handbuch gelesen, dass es veraltet ist und -Istattdessen verwendet werden sollte. Und wird @es als Begrenzer für Anfang und Ende des Musters verwendet?
Edson Horacio Junior
2
Die Frage ist jedoch speziell für Linux.
Pymarco
6
Auf osx ist das ok:grep -rli 'old-word' * | xargs -I@ sed -i '' 's/2.0.0/latest/g' @
Philippe Sultan
1
Es wäre schön, wenn Sie einige der Optionen ( rli) und das @Zeichen zum Beispiel
Roymunson
37

Das hat bei mir funktioniert:

find ./ -type f -exec sed -i 's/string1/string2/' {} \;

Dies war jedoch nicht der Fall : sed -i 's/string1/string2/g' *. Vielleicht sollte "foo" nicht string1 und "bar" nicht string2 sein.

Kaspar L. Palgi
quelle
1
Dies liegt daran, dass sed den Platzhalter * anders behandelt. [abc] * bedeutet eine beliebige Anzahl von Zeichen der Menge {a, b, c}. [a-z0-9] * funktioniert ähnlich wie der Platzhalter *.
Thepiercingarrow
8
Unter OSX verwenden:find ./ -type f -exec sed -i '' -e 's/string1/string2/' {} \;
Shaheen Ghiassy
32

Es gibt einige Standardantworten, die bereits aufgelistet sind. Im Allgemeinen können Sie find verwenden, um die Dateien rekursiv aufzulisten und dann die Vorgänge mit sed oder perl auszuführen .

Für die meisten schnellen Anwendungen ist der Befehl rpl möglicherweise viel einfacher zu merken. Hier ist Ersatz (foo -> bar), rekursiv für alle Dateien:

rpl -R foo bar .

Sie müssen es wahrscheinlich installieren ( apt-get install rploder ähnliches).

Für härtere Jobs, die reguläre Ausdrücke und Rückersetzung oder das Umbenennen von Dateien sowie das Suchen und Ersetzen umfassen, ist das allgemeinste und leistungsfähigste Tool, das mir bekannt ist, repren , ein kleines Python-Skript, das ich vor einiger Zeit für einige geschrieben habe dornigere Umbenennungs- und Refactoring-Aufgaben. Die Gründe, die Sie vielleicht bevorzugen, sind:

  • Unterstützt das Umbenennen von Dateien sowie das Suchen und Ersetzen von Dateiinhalten.
  • Sehen Sie sich die Änderungen an, bevor Sie die Suche und das Ersetzen durchführen.
  • Unterstützt reguläre Ausdrücke mit Rücksubstitution, ganzen Wörtern, Groß- und Kleinschreibung beachten und Groß- / Kleinschreibung beibehalten (foo -> bar, Foo -> Bar, FOO -> BAR ersetzen).
  • Funktioniert mit mehreren Ersetzungen, einschließlich Swaps (foo -> bar und bar -> foo) oder Sätzen nicht eindeutiger Ersetzungen (foo -> bar, f -> x).

Um es zu benutzen , pip install repren. Überprüfen Sie die README für Beispiele.

jlevy
quelle
1
Wow, Repren ist ausgezeichnet! Ich habe es nur verwendet, um einen Teil eines Wortes innerhalb von Klassennamen, Methoden und Variablen zu ändern, während Dateien so umbenannt wurden, dass sie mit mehr als 1.000 C ++ - Header- und Quelldateien übereinstimmen, und es hat beim ersten Mal mit einem Befehl perfekt funktioniert. Vielen Dank!
Bob Kocisko
29

So ersetzen Sie eine Zeichenfolge in mehreren Dateien:

grep -rl string1 somedir/ | xargs sed -i 's/string1/string2/g'

Z.B

grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'

Quellblog

Djacomo
quelle
20

Verwenden Sie den folgenden Befehl, um einen Pfad in Dateien zu ersetzen (Vermeiden von Escapezeichen):

sed -i 's@old_path@new_path@g'

Das @ -Zeichen bedeutet, dass alle Sonderzeichen in einer folgenden Zeichenfolge ignoriert werden sollten.

Ilya Suzdalnitski
quelle
2
Genau das, wonach ich in all den anderen Antworten gesucht habe. Nämlich, wie man mit Sonderzeichen umgeht, beispielsweise wenn man eine Zeichenfolge ändert, die ein Pfad ist. Vielen Dank. Schien wie ein großes Versehen in den anderen Antworten.
inspiriert
19

Falls Ihre Zeichenfolge einen Schrägstrich (/) enthält, können Sie das Trennzeichen in '+' ändern.

find . -type f -exec sed -i 's+http://example.com+https://example.com+g' {} +

Dieser Befehl würde rekursiv im aktuellen Verzeichnis ausgeführt.

gopiariv
quelle
Vielen Dank! Geholfen Änderung einer Belastung von Referenzen ../domain.comzudomain.com
Jack Rogers
12

Die ersten Zeilenvorkommen von "foo" werden durch "bar" ersetzt. Und Sie können die zweite Zeile verwenden, um zu überprüfen.

grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
grep 'foo' -r * | awk -F: {'print $1'} | sort -n | uniq -c
Jiasir
quelle
6
Warum verlinkst du auf dein Blog? Es enthält genau den gleichen Text wie Ihre Antwort.
DavidPostill
1
Ich maggrep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
Prachi
10

Wenn Sie eine Liste von Dateien haben, die Sie verwenden können

replace "old_string" "new_string" -- file_name1 file_name2 file_name3

Wenn Sie alle Dateien haben, können Sie verwenden

replace "old_string" "new_string" -- *

Wenn Sie eine Liste von Dateien mit Erweiterung haben, können Sie verwenden

replace "old_string" "new_string" -- *.extension
Pawel Dubiel
quelle
2
Eigentlich sollte "--file" nur "-" sein, zumindest in meiner Version
simpleuser
4
Dieses Dienstprogramm wird in MySQL-Paketen verteilt.
Dmitry Ginzburg
2
Ich würde mich jedoch über eine Lösung freuen, die ohne Angabe einer regulären Zeile als regulärer Ausdruck funktioniert.
Dmitry Ginzburg
1
Dies funktioniert gut - und wenn Sie alle Zeichenfolgen in mehreren Dateien ersetzen möchten, die beispielsweise mit ".txt" enden, können Sie dies einfach tunreplace "old_string" "new_string" -- *.txt
tsveti_iko
1
Es ist besser hinzuzufügen, woher Sie dieses replaceDienstprogramm beziehen. Ohne diese Informationen ist diese Antwort unvollständig.
Sitesh
8

"Sie könnten auch find und sed verwenden, aber ich finde, dass diese kleine Perl-Linie gut funktioniert.

perl -pi -w -e 's/search/replace/g;' *.php
  • -e bedeutet, die folgende Codezeile auszuführen.
  • -i bedeutet direkt bearbeiten
  • -w Warnungen schreiben
  • -p Schleife

"(Auszug aus http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php )

Meine besten Ergebnisse kommen von der Verwendung von Perl und Grep (um sicherzustellen, dass die Datei den Suchausdruck hat)

perl -pi -w -e 's/search/replace/g;' $( grep -rl 'search' )
Alejandro Salamanca Mazuelo
quelle
8

Da Sie nach der Zeichenfolge suchen searchund diese replacedurch mehrere Dateien ersetzen möchten , ist dies meine kampferprobte, einzeilige Formel :

grep -RiIl 'search' | xargs sed -i 's/search/replace/g'

Schnelle grep Erklärung:

  • -R - rekursive Suche
  • -i - Groß- und Kleinschreibung wird nicht berücksichtigt
  • -I - Binärdateien überspringen (Sie möchten Text, oder?)
  • -l- Drucken Sie eine einfache Liste als Ausgabe. Wird für die anderen Befehle benötigt

Die grep-Ausgabe wird dann an sed (über xargs) weitergeleitet, das zum tatsächlichen Ersetzen von Text verwendet wird. Das -iFlag ändert die Datei direkt. Entfernen Sie es für eine Art "Trockenlauf" -Modus.

Ignorant
quelle
4

Ich habe meine eigene Lösung zusammengestellt, bevor ich diese Frage (und Antworten) gefunden habe. Ich habe nach verschiedenen Kombinationen von "Ersetzen", "Mehrere" und "XML" gesucht, da dies meine Anwendung war, aber diese bestimmte nicht gefunden habe.

Mein Problem: Ich hatte Spring-XML-Dateien mit Daten für Testfälle, die komplexe Objekte enthielten. Ein Refactor für den Java-Quellcode hat viele Klassen geändert und galt nicht für die XML-Datendateien. Um die Testfalldaten zu speichern, musste ich alle Klassennamen in allen XML-Dateien ändern, die auf mehrere Verzeichnisse verteilt waren. Während des Speicherns von Sicherungskopien der ursprünglichen XML-Dateien (obwohl dies kein Muss war, da die Versionskontrolle mich hier speichern würde).

Ich suchte nach einer Kombination von find+ sed, weil es in anderen Situationen für mich funktionierte, aber nicht mit mehreren Ersetzungen gleichzeitig.

Dann fand ich ask ubuntu response und es half mir beim Aufbau meiner Kommandozeile:

find -name "*.xml" -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;

Und es hat perfekt funktioniert (nun, mein Fall hatte sechs verschiedene Ersetzungen). Beachten Sie jedoch, dass alle * .xml-Dateien im aktuellen Verzeichnis berührt werden. Aus diesem Grund und wenn Sie gegenüber einem Versionskontrollsystem rechenschaftspflichtig sind, möchten Sie möglicherweise zuerst filtern und nur an seddiejenigen weitergeben, die tatsächlich die gewünschten Zeichenfolgen haben. mögen:

find -name "*.xml" -exec grep -e "firstWord" -e "secondWord" -e "thirdWord" {} \; -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;
manuelvigarcia
quelle
und für Windows habe ich gerade herausgefunden, dass es eine Möglichkeit gibt, die Zeichenfolge in einem Befehl zu finden - ich habe noch nicht überprüft, wie sie ersetzt findstr /spin /c:"quéquieresbuscar" *.xml werden soll : Es wird praktisch sein.
Manuelvigarcia
3
grep --include={*.php,*.html} -rnl './' -e "old" | xargs -i@ sed -i 's/old/new/g' @
Dennis
quelle
3

Wirklich lahm, aber ich konnte keinen der sed-Befehle unter OSX zum Laufen bringen, also habe ich stattdessen diese dumme Sache gemacht:

:%s/foo/bar/g
:wn

^ - kopiere diese drei Zeilen in meine Zwischenablage (ja, füge die abschließende neue Zeile hinzu), dann:

vi *

und halten Sie Befehl-v gedrückt, bis angezeigt wird, dass keine Dateien mehr vorhanden sind.

Dumm ... hacky ... effektiv ...

Justin
quelle
3

Auf einem MacBook Pro habe ich Folgendes verwendet (inspiriert von https://stackoverflow.com/a/19457213/6169225 ):

sed -i '' -e 's/<STR_TO_REPLACE>/<REPLACEMENT_STR>/g' *

-i '' stellt sicher, dass Sie keine Backups erstellen.

-e für moderne Regex.

Marquistador
quelle
3
-esagt sed nur, dass das nächste Token ein Befehl ist. Verwenden Sie -Estattdessen für erweiterte reguläre Ausdrücke .
Benjamin W.
2

Der Stream-Editor ändert mehrere Dateien "inplace", wenn er mit dem -iSchalter aufgerufen wird , der eine Sicherungsdatei als Argument verwendet. Damit

sed -i.bak 's/foo/bar/g' *

Ersetzt foodurch barin allen Dateien in diesem Ordner, steigt jedoch nicht in Unterordner ab. Dadurch wird jedoch .bakfür jede Datei in Ihrem Verzeichnis eine neue Datei generiert . Um dies rekursiv für alle Dateien in diesem Verzeichnis und allen seinen Unterverzeichnissen durchzuführen, benötigen Sie einen Helfer find, um den Verzeichnisbaum zu durchlaufen.

find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' *

findErmöglicht Ihnen weitere Einschränkungen hinsichtlich der zu ändernden Dateien, indem Sie find ./ -name '*.php' -or -name '*.html' -print0ggf. weitere Argumente angeben.


Hinweis: GNU sederfordert keine Dateiende und sed -i 's/foo/bar/g' *funktioniert auch. FreeBSD sedverlangt eine Erweiterung, lässt aber einen Zwischenraum dazwischen, sed -i .bak s/foo/bar/g *funktioniert also.

Anaphory
quelle
2

Skript für Multiedit-Befehl

multiedit [-n PATTERN] OLDSTRING NEWSTRING

Aus Kaspars Antwort habe ich ein Bash-Skript erstellt, um Befehlszeilenargumente zu akzeptieren und optional die Dateinamen zu begrenzen, die einem Muster entsprechen. Speichern Sie in Ihrem $ PATH und machen Sie es ausführbar. Verwenden Sie dann einfach den obigen Befehl.

Hier ist das Skript:

#!/bin/bash
_help="\n
Replace OLDSTRING with NEWSTRING recursively starting from current directory\n
multiedit [-n PATTERN] OLDSTRING NEWSTRING\n

[-n PATTERN] option limits to filenames matching PATTERN\n
Note: backslash escape special characters\n
Note: enclose STRINGS with spaces in double quotes\n
Example to limit the edit to python files:\n
multiedit -n \*.py \"OLD STRING\" NEWSTRING\n"

# ensure correct number of arguments, otherwise display help...
if [ $# -lt 2 ] || [ $# -gt 4 ]; then echo -e $_help ; exit ; fi
if [ $1 == "-n" ]; then  # if -n option is given:
        # replace OLDSTRING with NEWSTRING recursively in files matching PATTERN
        find ./ -type f -name "$2" -exec sed -i "s/$3/$4/g" {} \;
else
        # replace OLDSTRING with NEWSTRING recursively in all files
        find ./ -type f -exec sed -i "s/$1/$2/" {} \;
fi
BBW vor Windows
quelle
1

Wenn die Datei Backslashes enthält (normalerweise Pfade), können Sie Folgendes versuchen:

sed -i -- 's,<path1>,<path2>,g' *

Ex:

sed -i -- 's,/foo/bar,/new/foo/bar,g' *.sh (in all shell scripts available)
Shaik Amanulla
quelle
1

Um meinen persönlichen englischen Knoten beizubehalten, habe ich ein Dienstprogramm-Skript geschrieben, mit dessen Hilfe mehrere Paare alter / neuer Zeichenfolgen für alle Dateien in einem Verzeichnis rekursiv ersetzt werden können.

Die mehreren Paare alter / neuer Zeichenfolgen werden in einer Hash-Map verwaltet.

Das Verzeichnis kann über die Befehlszeile oder die Umgebungsvariable festgelegt werden. Die Zuordnung ist im Skript fest codiert. Sie können jedoch den Code ändern, der bei Bedarf aus einer Datei geladen werden soll.

Aufgrund einiger neuer Funktionen ist Bash 4.2 erforderlich.

en_standardize.sh:

#! /bin/bash
# (need bash 4.2+,)
# 
# Standardize phonetic symbol of English.
# 
# format:
#   en_standardize.sh [<dir>]
# 
# params:
# * dir
#   target dir, optional,
#   if not specified then use environment variable "$node_dir_en",
#   if both not provided, then will not execute,
# * 
# 

paramCount=$#

# figure target dir,
if [ $paramCount -ge 1 ]; then # dir specified
    echo -e "dir specified (in command):\n\t$1\n"
    targetDir=$1
elif [[ -v node_dir_en ]]; then # environable set,
    echo -e "dir specified (in environment vairable):\n\t$node_dir_en\n"
    targetDir=$node_dir_en
else # environable not set,
    echo "dir not specified, won't execute"
    exit
fi

# check whether dir exists,
if [ -d $targetDir ]; then
    cd $targetDir
else
    echo -e "invalid dir location:\n\t$targetDir\n"
    exit
fi

# initial map,
declare -A itemMap
itemMap=( ["ɪ"]="i" ["ː"]=":" ["ɜ"]="ə" ["ɒ"]="ɔ" ["ʊ"]="u" ["ɛ"]="e")

# print item maps,
echo 'maps:'
for key in "${!itemMap[@]}"; do
    echo -e "\t$key\t->\t${itemMap[$key]}"
done
echo -e '\n'

# do replace,
for key in "${!itemMap[@]}"; do
    grep -rli "$key" * | xargs -i@ sed -i "s/$key/${itemMap[$key]}/g" @
done

echo -e "\nDone."
exit
Eric Wang
quelle
1

Die Verwendung des Befehls ack wäre viel schneller:

ack '25 Essex' -l | xargs sed -i 's/The\ fox \jump/abc 321/g'

Auch wenn Sie im Suchergebnis einen Leerraum haben. Du musst ihm entkommen.

Patoshi パ ト シ
quelle
0

Ich gebe ein Beispiel für die Behebung eines häufigen Shebang-Fehlers in Python-Quellen.

Sie können den grep / sed-Ansatz ausprobieren. Hier ist eine, die mit GNU sed funktioniert und kein Git-Repo kaputt macht:

$ grep -rli --exclude '*.git*' '#!/usr/bin/python' . | xargs -I {} \
gsed -i '' -e 's/#!\/usr\/bin\/python/#!\/usr\/bin\/env python/' {}

Oder du kannst greptile verwenden :)

$ greptile -x .py -l -i -g '#!/usr/bin/env python' -r '#!/usr/bin/python' .

Ich habe gerade das erste Skript getestet und das zweite sollte auch funktionieren. Seien Sie vorsichtig mit Escape-Zeichen. Ich denke, es sollte in den meisten Fällen einfacher sein, Greptile zu verwenden. Natürlich können Sie mit sed viele interessante Dinge tun, und dafür ist es möglicherweise vorzuziehen, die Verwendung mit xargs zu beherrschen.

exa
quelle
0

Ich habe diesen aus einem anderen Beitrag gefunden (kann mich nicht erinnern, welcher) und obwohl er nicht der eleganteste ist, ist er einfach und hat mir als unerfahrener Linux-Benutzer keine Probleme bereitet

for i in *old_str* ; do mv -v "$i" "${i/\old_str/new_str}" ; done

Wenn Sie Leerzeichen oder andere Sonderzeichen haben, verwenden Sie ein \

for i in *old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done

Verwenden Sie für Zeichenfolgen in Unterverzeichnissen **

for i in *\*old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done
Kyle Turck
quelle
0

Der folgende Befehl kann verwendet werden, um zuerst die Dateien zu durchsuchen und die Dateien zu ersetzen:

find . | xargs grep 'search string' | sed 's/search string/new string/g'

Zum Beispiel

find . | xargs grep abc | sed 's/abc/xyz/g'
Amit
quelle
0

Es gibt einen einfacheren Weg, indem Sie eine einfache Skriptdatei verwenden:

   # sudo chmod +x /bin/replace_string_files_present_dir

öffne die Datei in gedit oder einem Editor deiner Wahl, ich benutze gedit hier.

   # sudo gedit /bin/replace_string_files_present_dir

Fügen Sie dann im Editor Folgendes in die Datei ein

   #!/bin/bash
   replace "oldstring" "newstring" -- *
   replace "oldstring1" "newstring2" -- *
   #add as many lines of replace as there are your strings to be replaced for 
   #example here i have two sets of strings to replace which are oldstring and 
   #oldstring1 so I use two replace lines.

Speichern Sie die Datei, schließen Sie gedit , Ihr Terminal oder schließen Sie es einfach und starten Sie es, um das neue Skript zu laden, das Sie hinzugefügt haben.

Navigieren Sie zu dem Verzeichnis, in dem Sie mehrere Dateien bearbeiten möchten. Dann renne:

  #replace_string_files_present_dir

Drücken Sie die Eingabetaste , und dies wird die automatisch ersetzen oldstring und oldstring1 in allen Dateien , die sie mit dem richtigen enthalten newstring und newstring1 sind.

Es werden alle Verzeichnisse und Dateien übersprungen, die nicht die alten Zeichenfolgen enthalten.

Dies kann dazu beitragen, die mühsame Eingabe zu vermeiden, falls Sie mehrere Verzeichnisse mit Dateien haben, die durch Zeichenfolgen ersetzt werden müssen. Sie müssen lediglich zu jedem dieser Verzeichnisse navigieren und dann Folgendes ausführen:

#replace_string_files_present_dir

Alles, was Sie tun müssen, ist sicherzustellen, dass Sie alle Ersatzzeichenfolgen aufgenommen oder hinzugefügt haben, wie ich Ihnen oben gezeigt habe:

replace "oldstring" "newstring" -- *

am Ende der Datei / bin / replace_string_files_present_dir .

Um eine neue Ersetzungszeichenfolge hinzuzufügen, öffnen Sie einfach das von uns erstellte Skript, indem Sie Folgendes in das Terminal eingeben:

sudo gedit /bin/replace_string_files_present_dir

Machen Sie sich keine Sorgen über die Anzahl der hinzugefügten Ersetzungszeichenfolgen. Sie haben keine Auswirkung, wenn die alte Zeichenfolge nicht gefunden wird.

briancollins081
quelle
Wenn Leute in Bash fragen, wie man $ {was auch immer} macht, fragen sie normalerweise nach einer kompakten Version, die in ein Skript oder eine CI-Jobanweisung aufgenommen werden soll (z. B. a .gitlab-ci.ymloder a travis.yml). Jede Umkehrung, die darin besteht, ein Skript zu schreiben, um es später auszuführen, ist ein Anti-Pattern, da Sie dann die Skript-Erstellung
per
-4

$ replace "From" "To" - `find / path / to / folder -type f`

(replace - ein Dienstprogramm zum Ersetzen von Zeichenfolgen des MySQL-Datenbanksystems)

Bashconsole
quelle