Suchen und ersetzen in Datei, und überschreiben Sie die Datei funktioniert nicht, es leert die Datei
Ich würde gerne ein suchen und ersetzen auf eine HTML-Datei über die Befehlszeile.
Mein Befehl sieht ungefähr so aus:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html
Wenn ich diesen starte, und schauen Sie auf die Datei, danach ist es leer. Gelöscht-der Inhalt meiner Datei.
Wenn ich dieses nach dem wiederherstellen der Datei wieder:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
Den stdout
ist der Inhalt der Datei, und suchen und ersetzen ausgeführt wurde.
Warum ist das passiert?
- Perl-alternative:
perl -pi -w -e 's/STRING_TO_REPLACE/REPLACE_WITH/g;' index.html
- viel Verwandte
sed
- Befehl, um einen string und Ersetze die ganze Zeile: stackoverflow.com/questions/11245144/... - Siehe auch dies: Wie man Lesen und schreiben die gleiche Datei in der gleichen Rohrleitung immer "fail"? auf Unix & Linux SO.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn die shell sieht
> index.html
in die Kommando-Zeile es öffnet sich das Dateiindex.html
für schreiben, abwischen alle Ihre vorherigen Inhalt.Dieses Problem zu beheben, müssen Sie passieren die
-i
optionsed
um die änderungen inline und erstellen Sie eine Sicherungskopie der ursprünglichen Datei, bevor Sie die änderungen in-place:Ohne .bak schlägt der Befehl fehl auf einigen Plattformen, wie Mac OSX.
truncates the file
stattopens the file
macht es wahrscheinlich klarer.invalid character code f
Fehler, wenn ich versuchte es mit einer Datei namens foo ohne die Angabe einer Erweiterung..sed -i '' 's/blah/xx/g'
.bak
nachsed -i
?sed --in-place ".bak" s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index_new.html
es würde gearbeitet haben. Die Verwirrung rührt von der Tatsache, dass wir von Links nach rechts gelesen. Was passiert ist jedoch, dass die Datei gekürzt erste in der Vorbereitung für den sed-Befehl, der folgt, die endet, das in einem bereits leeren Datei.Alternative, nützlich, Muster:
Dass hat viel die gleiche Wirkung, ohne die
-i
option, und zusätzlich bedeutet, dass, wenn die sed-Skript aus irgendeinem Grund ausfällt, wird die Eingabe-Datei nicht verändern. Weiter, wenn die Eingabe erfolgreich ist, gibt es keine backup-Datei herumliegen. Diese Art von idiom nützlich sein können Makefiles.Ganz viele seds haben das
-i
option, aber nicht alle von Ihnen; die posix-sed ist eine, die nicht. Wenn Sie sind ein Ziel für die Portabilität, daher ist es am besten vermieden werden.... && mv index.html{.tmp,}
sh
(wenn ich mich Recht erinnere) nicht haben, dass{...}
expansion. In einem Makefile können Siesh
eher alsbash
, so dass, wenn Sie sind ein Ziel für die Portabilität (oder posixness), dann brauchen Sie, um zu vermeiden, dass die Konstruktion.mv index.html $(echo index.html | sed -e 'script')
Bedeutet dies eine Globale in-place-substitution auf die Datei index.html. Angabe der Zeichenfolge verhindert, dass Probleme mit Leerzeichen in der Abfrage und Austausch.
verwenden sed die option-i, z.B.
's/STRING_TO_REPLACE/REPLACE_WITH/g'
Ändern mehrere Dateien und speichern eine Sicherungskopie von jedem als *.bak):
wird alle Dateien im Verzeichnis und ersetzen
|
mitx
dies wird als ein "Perl-pie" (einfach wie ein Kuchen)
sed
als Voraussetzung, es nur verwendet, da das tool schon ausprobiert.Sollten Sie versuchen, mithilfe der option
-i
für in-place-Bearbeitung.Wenn Sie eine Verknüpfung Hinzugefügt werden, versuchen Sie dies. Suchen Sie nach der URL wie oben (beginnend mit https und Ende with.com hier) und ersetzen Sie es mit einem URL-string. Ich habe eine variable verwendet
$pub_url
hier.s
bedeutet hier die Suche und dieg
bedeutet weltweiten Austausch.Es funktioniert !
Warnung: dies ist eine gefährliche Methode! Es beschimpft die i/o-Puffer in linux und mit spezifischen Optionen, die Pufferung, die es verwaltet, um die Arbeit an kleinen Dateien. Es ist eine interessante kuriosität. Aber verwenden Sie es nicht für eine Reale situation!
Neben der
-i
Möglichkeitsed
Sie können die
tee
utility.Vom
man
:So, die Lösung wäre:
-- hier die
tee
wiederholt, um sicherzustellen, dass die pipeline zwischengespeichert. Dann alle Befehle in der pipeline sind blockiert, bis Sie bekommen input, um die Arbeit auf. Jeder Befehl in der pipeline beginnt, wenn der upstream-Befehle geschrieben habe, 1 Puffer von bytes (die Größe ist definiert irgendwo) an den Eingang des Befehls. Also der Letzte Befehltee index.html
öffnet die Datei zum schreiben und daher leert ihn, läuft nach der vorgeschalteten Rohrleitung beendet und das Ergebnis wird in den Puffer in der pipeline.Wahrscheinlich das folgende nicht funktionieren:
-- es laufen wird, werden beide Befehle in die pipeline zur gleichen Zeit, ohne zu blockieren. (Ohne die Blockierung der pipeline passieren soll, die Byte-Zeile anstelle von Puffer von buffer. Gleiche, wie wenn du laufen
cat | sed s/bar/GGG/
. Ohne zu blockieren es mehr interaktive und Rohrleitungen in der Regel nur 2 Befehle ausführen, ohne Pufferung und blockieren. Mehr pipelines gepuffert werden.) Dietee index.html
öffnet die Datei zum schreiben und es geleert wird. Jedoch, wenn Sie die Pufferung immer auf die zweite version wird auch funktionieren.>
, aber der Punkt steht, dass es eine gebrochene Lösung ist, die wahrscheinlich zu Datenverlust führen).Das problem mit dem Befehl
ist, dass
file
ist abgeschnitten von der shell vor der sed tatsächlich bekommt, um es zu verarbeiten. Als Ergebnis erhalten Sie eine leere Datei.Die sed Weg, dies zu tun ist die Verwendung
-i
zu Bearbeiten, wie andere Antworten vorgeschlagen. Dies ist jedoch nicht immer, was Sie wollen.-i
erstellt eine temporäre Datei, die dann verwendet werden, um die Originaldatei zu ersetzen. Dies ist problematisch, wenn Ihre ursprüngliche Datei war ein link (der link wird ersetzt durch eine normale Datei). Wenn Sie die Notwendigkeit der Erhaltung der links, die Sie verwenden können, eine temporäre variable zum speichern der Ausgabe des sed schreiben, bevor es zurück in die Datei, wie hier:Besser noch, verwenden Sie
printf
stattecho
seitecho
ist wahrscheinlich Prozess\\
als\
in einigen shells (z.B. Bindestrich):sed 'code' file > file.tmp; cat file.tmp > file; rm file.tmp
Und die
ed
Antwort:Wiederholen, was codaddict beantwortet, die shell übernimmt die Umleitung ersten, wischen aus der "input.html" Datei, und dann die shell ruft den "sed" Befehl und übergibt eine jetzt leere Datei.
ed
version" vonsed
Antworten? Leistung bringt es schneller?sed
s nicht implementieren-i
Bearbeiten in-place.ed
ist allgegenwärtig und lässt Sie speichern Sie Ihre änderungen an der ursprünglichen Datei. Plus, ist es immer gut haben viele der Werkzeuge, die in Ihrem kit.Können Sie Vim im Ex-Modus:
%
wählen Sie alle Zeilenx
speichern und schließenIch war auf der Suche die option wo ich definieren kann, das line-Sortiment und die Antwort gefunden. Zum Beispiel will ich ändern host1 zu host2 aus Zeile 36-57.
Können Sie gi-option zum ignorieren der groß-und Kleinschreibung.
Mit allem Respekt vor den oben korrekten Antworten, es ist immer eine gute Idee, um "trocken laufen" scripts wie, dass, so dass Sie nicht beschädigt Ihrer Datei und starten wieder von vorne an.
Holen Sie einfach Ihr Skript zu verschütten, die Ausgabe auf der Kommandozeile anstatt in die Datei zu schreiben, Z. B. so:
ODER
Diese Weise können Sie sehen und überprüfen Sie die Ausgabe des Befehls, ohne dass die Datei abgeschnitten.