Ich möchte ein Suchen und Ersetzen in einer HTML-Datei über die Befehlszeile ausführen.
Mein Befehl sieht ungefähr so aus:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html
Wenn ich dies ausführe und die Datei anschließend betrachte, ist sie leer. Es hat den Inhalt meiner Datei gelöscht.
Wenn ich dies nach dem erneuten Wiederherstellen der Datei ausführe:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
Das stdout
ist der Inhalt der Datei, und das Suchen und Ersetzen wurde ausgeführt.
Warum passiert dies?
shell
unix
sed
io-redirection
BBales
quelle
quelle
perl -pi -w -e 's/STRING_TO_REPLACE/REPLACE_WITH/g;' index.html
sed
Befehl, um eine Zeichenfolge zu finden und die gesamte Zeile zu ersetzen: stackoverflow.com/questions/11245144/…Antworten:
Wenn die Shell
> index.html
in der Befehlszeile sieht , öffnet sie die Dateiindex.html
zum Schreiben und löscht alle vorherigen Inhalte.Um dies zu beheben, müssen Sie die
-i
Option übergeben,sed
um die Änderungen inline vorzunehmen und eine Sicherungskopie der Originaldatei zu erstellen, bevor die Änderungen direkt vorgenommen werden:Ohne die .bak schlägt der Befehl auf einigen Plattformen wie Mac OSX fehl.
quelle
truncates the file
stattopens the file
wahrscheinlich macht es klarer.sed -i '' 's/blah/xx/g'
.bak
danachsed -i
?Ein alternatives, nützliches Muster ist:
-i
Dies hat fast den gleichen Effekt, ohne die Option zu verwenden, und bedeutet außerdem, dass die Eingabedatei nicht überlastet wird, wenn das sed-Skript aus irgendeinem Grund fehlschlägt. Wenn die Bearbeitung erfolgreich ist, liegt keine Sicherungsdatei mehr herum. Diese Art von Redewendung kann in Makefiles nützlich sein.Sehr viele Samen haben die
-i
Option, aber nicht alle; Das Posix Sed ist eines, das dies nicht tut. Wenn Sie Portabilität anstreben, sollten Sie dies am besten vermeiden.quelle
... && mv index.html{.tmp,}
sh
(wenn ich mich richtig erinnere) hat diese{...}
Erweiterung nicht. In einem Makefile verwenden Sie möglicherweisesh
eher alsbash
. Wenn Sie also Portabilität (oder Posixität) anstreben, müssen Sie diese Konstruktion vermeiden.Dies führt eine globale direkte Ersetzung in der Datei index.html durch. Das Zitieren der Zeichenfolge verhindert Probleme mit Leerzeichen bei der Abfrage und beim Ersetzen.
quelle
Verwenden Sie die Option -i von sed, z
quelle
's/STRING_TO_REPLACE/REPLACE_WITH/g'
-i
die direkte Bearbeitung von Dateien durch , daher ist es nicht sinnvoll, sie mit stdin- Eingaben zu kombinieren .So ändern Sie mehrere Dateien (und speichern jeweils ein Backup als * .bak):
nehmen Sie alle Dateien im Verzeichnis und ersetzen
|
mitx
dieser eine „Perl pie“ (einfach wie eine Torte) genanntquelle
sed
als Anforderung angegeben, sondern nur als bereits ausprobiertes Tool verwendet.Sie sollten versuchen, die Option
-i
für die direkte Bearbeitung zu verwenden.quelle
Wenn Sie einen Link hinzufügen möchten, versuchen Sie dies. Suchen Sie wie oben nach der URL (beginnend mit https und endend mit.com hier) und ersetzen Sie sie durch eine URL-Zeichenfolge. Ich habe
$pub_url
hier eine Variable verwendet .s
bedeutet hier Suche undg
bedeutet globalen Ersatz.Es klappt !
quelle
Achtung: Dies ist eine gefährliche Methode! Es missbraucht die E / A-Puffer unter Linux und schafft es mit bestimmten Pufferoptionen, mit kleinen Dateien zu arbeiten. Es ist eine interessante Neugier. Aber verwenden Sie es nicht für eine reale Situation!
Neben der
-i
Optionsed
können Sie dastee
Dienstprogramm verwenden .Von
man
:Die Lösung wäre also:
- Hier wird das
tee
wiederholt, um sicherzustellen, dass die Pipeline gepuffert ist. Dann werden alle Befehle in der Pipeline blockiert, bis sie Eingaben zur Bearbeitung erhalten. Jeder Befehl in der Pipeline startet, wenn die Upstream-Befehle 1 Byte-Puffer (die Größe ist irgendwo definiert ) in die Eingabe des Befehls geschrieben haben. Der letzte Befehltee index.html
, der die Datei zum Schreiben öffnet und daher leert, wird ausgeführt, nachdem die Upstream-Pipeline beendet wurde und sich die Ausgabe im Puffer innerhalb der Pipeline befindet.Höchstwahrscheinlich funktioniert Folgendes nicht:
- Es werden beide Befehle der Pipeline gleichzeitig ausgeführt, ohne dass sie blockiert werden. (Ohne Blockierung sollte die Pipeline die Bytes Zeile für Zeile anstelle von Puffer für Puffer passieren. Wie beim Ausführen
cat | sed s/bar/GGG/
. Ohne Blockierung ist sie interaktiver und normalerweise werden Pipelines mit nur 2 Befehlen ohne Pufferung und Blockierung ausgeführt. Längere Pipelines werden gepuffert.) Dertee index.html
Wille Öffnen Sie die Datei zum Schreiben und sie wird geleert. Wenn Sie die Pufferung jedoch immer aktivieren, funktioniert auch die zweite Version.quelle
>
, aber der Punkt ist, dass es sich um eine fehlerhafte Lösung handelt, die wahrscheinlich zu Datenverlust führt.)Das Problem mit dem Befehl
ist, dass
file
es von der Shell abgeschnitten wird, bevor sed es tatsächlich verarbeiten kann. Als Ergebnis erhalten Sie eine leere Datei.Die beste Möglichkeit, dies zu tun, besteht darin
-i
, die Bearbeitung an Ort und Stelle durchzuführen, wie in anderen Antworten vorgeschlagen. Dies ist jedoch nicht immer das, was Sie wollen.-i
erstellt eine temporäre Datei, die dann zum Ersetzen der Originaldatei verwendet wird. Dies ist problematisch, wenn Ihre Originaldatei ein Link war (der Link wird durch eine reguläre Datei ersetzt). Wenn Sie Links beibehalten müssen, können Sie die Ausgabe von sed mithilfe einer temporären Variablen speichern, bevor Sie sie wie folgt in die Datei zurückschreiben:Besser noch, verwenden Sie
printf
anstelle vonecho
daecho
wird wahrscheinlich\\
wie\
in einigen Shells (z. B. Strich) verarbeitet:quelle
sed 'code' file > file.tmp; cat file.tmp > file; rm file.tmp
Und die
ed
Antwort:Um es zu wiederholen , was codaddict beantwortet , die Schalengriffe die Umleitung erste , die „input.html“ Datei auszulöschen, und dann ruft die Shell den „sed“ -Befehl es nun leere Datei übergeben.
quelle
ed
Version" dersed
Antworten geben? funktioniert es schneller?sed
s implementieren nicht,-i
um direkt zu bearbeiten.ed
ist allgegenwärtig und ermöglicht es Ihnen, Ihre Änderungen in der Originaldatei zu speichern. Außerdem ist es immer gut, viele Werkzeuge in Ihrem Kit zu haben.Sie können Vim im Ex-Modus verwenden:
%
Wählen Sie alle Zeilen ausx
speichern und schließenquelle
Ich habe nach der Option gesucht, mit der ich den Linienbereich definieren und die Antwort finden kann. Zum Beispiel möchte ich Host1 von Zeile 36-57 in Host2 ändern.
Sie können auch die Option gi verwenden, um die Groß- und Kleinschreibung zu ignorieren.
quelle
Bei allem Respekt vor den oben genannten richtigen Antworten ist es immer eine gute Idee, solche Skripte "trocken laufen" zu lassen, damit Sie Ihre Datei nicht beschädigen und von vorne beginnen müssen.
Lassen Sie Ihr Skript einfach die Ausgabe in die Befehlszeile übertragen, anstatt sie beispielsweise so in die Datei zu schreiben:
ODER
Auf diese Weise können Sie die Ausgabe des Befehls anzeigen und überprüfen, ohne dass Ihre Datei abgeschnitten wird.
quelle