Ich habe in meinem Projekt die Anforderung, vorhandenen Text in einer Datei foo
durch einen anderen Text wie den fooofoo
folgenden zu ersetzen :
abc.txt
name
foo
foo1
Also habe ich versucht:
sed -i "s/foo/fooofoo/g" abc.txt
Ich erhalte jedoch diesen Fehler:
sed: illegale Option -
i
Ich habe in dem Handbuch gefunden, dass ich verwenden muss:
sed -i\ "s/foo/fooofoo/g" abc.txt
Dies funktioniert jedoch auch nicht.
Ich habe Alternativen in perl
und awk
auch gefunden, aber eine Lösung in Solaris sed
wäre sehr dankbar.
Ich benutze diese Version von Bash:
GNU Bash, Version 3.2.57 (1) -Veröffentlichung (sparc-sun-solaris2.10)
text-processing
sed
solaris
tpsaitwal
quelle
quelle
/usr/gnu/bin/sed
-i, um Unterstützung zu erhalten.Antworten:
Verwenden Sie
ed
. Es ist auf den meisten Plattformen verfügbar und kann Ihre Dateien direkt bearbeiten.Da
sed
basiert aufed
der Syntax zum Ersetzen von Mustern ist ähnlich:quelle
ed
stattex
nur neugierig? (Ich weiß, dass beide POSIX-kompatibel sind und ich habe mit den Spezifikationen verlinkt .;))ex
? Um Ihre Frage zu beantworten: Da ich nie benutze,ex
bin ich nicht damit vertraut. Übrigens habe ich Setups gesehen, bei denened
vorhanden war, aberex
nicht (aber nicht das Gegenteil) ... das bemerkenswerteste ist mein Laptop :)ex
Befehlen sehr vertraut . Allevi
Befehle, die Sie eingeben können und die mit einem Doppelpunkt beginnen, sindex
Befehle. Es gibt natürlich einige Vim-spezifische Erweiterungen, aber nur der Kernsatz von Befehlen ist unglaublich leistungsfähig und flexibel und bietet ausreichend Platz für Skriptbearbeitungen.ex
und doch nichted
.Wenn Sie GNU sed nicht installieren können, verwenden Sie:
Dies verwendet die Umleitung , um die Ausgabe von sed an eine temporäre Datei zu senden. Wenn sed erfolgreich abgeschlossen wurde, wird dies
abc.txt
mit der temporären Datei überschrieben .Wie aus dem Quellcode für GNU sed hervorgeht , ist genau dies der
sed -i
Fall. Das ist also ungefähr so effizient wiesed -i
.Wenn eine Möglichkeit
abc.tmp
besteht, die bereits besteht, möchten Sie möglicherweisemktemp
ein ähnliches Dienstprogramm verwenden, um den eindeutigen Namen für die temporäre Datei zu generieren.quelle
ed
, da es die gesamte Datei in den Speicher liest.Wenn Sie das Äquivalent von wollen
sed -i.bak
, ist es ziemlich einfach.Betrachten Sie dieses Skript für GNU sed:
Wir können einfach die markierte Linie durch ersetzen
Dadurch wird die vorhandene Datei als Backup verschoben und eine neue Datei geschrieben.
Wenn wir das Äquivalent von wollen
dann ist es etwas komplexer. Wir können die Datei zum Lesen als Standardeingabe öffnen und dann die Verknüpfung aufheben, bevor wir die Ausgabe von sed anweisen, sie zu ersetzen:
Wir machen das in einer Sub-Shell, so dass unser ursprünglicher Standard danach noch verfügbar ist. Es ist möglich, Eingänge zu schalten und ohne Unterschale zurückzuschalten, aber dieser Weg scheint mir klarer zu sein.
Beachten Sie, dass wir zuerst sorgfältig kopieren, anstatt eine neue
foo
Datei zu erstellen. Dies ist wichtig, wenn die Datei unter mehr als einem Namen bekannt ist (dh über feste Links verfügt) und Sie sicherstellen möchten, dass Sie die Links nicht unterbrechen .quelle
Zunächst sollten Sie wissen, dass der
i\
Befehl , auf den Sie sich beziehen, zum Einfügen einer Textzeile dient und nicht zum Zurückspeichern des bearbeiteten Textes in die Datei. Es gibt keine POSIX-spezifizierte Möglichkeit, dies zu verwendensed
.Was Sie können tun , ist Einsatz
ex
, die sich durch POSIX spezifiziert :Der
x
Befehl lautet "Speichern und beenden". Sie können auch verwendenwq
,x
ist aber kürzer.Das
%
Zeichen am Anfang des Ersatzbefehls bedeutet: "Wenden Sie diesen Befehl auf jede Zeile im Puffer an." Sie könnten1,$s/find/replace/g
auch verwenden.Ein wesentlicher Unterschied zwischen
ex
undsed
ist, dasssed
es sich um einen Stream- Editor handelt. Es arbeitet nur sequentiell, Zeile für Zeile.ex
ist weitaus flexibler als das, und in der Tat können Sie interaktive Textdateien direkt in bearbeitenex
. Es ist der unmittelbare Vorgänger vonvi
.quelle
Verwenden
sed
und keine sichtbare temporäre Datei:Sie können vermeiden, eine separate sichtbare "temporäre Datei" zu erstellen:
Erläuterung
Unix-ähnliche Systeme nicht tatsächlich die Inhalte von der Festplatte der Datei entfernen , bis es beide nicht verknüpfte in dem Dateisystem, und nicht in jedem Prozess zu öffnen. Sie können also
exec 3<
die Datei in der Shell öffnen, um sie in Dateideskriptor 3 zu lesen,rm
der Datei (die sie vom Dateisystem trennt), und dannsed
mit Dateideskriptor 3 aufrufen, der als Eingabe verwendet wird.Beachten Sie, dass dies sehr unterschiedlich ist:
Der Unterschied besteht darin, dass die Shell bei einem Befehl nur dieselbe Datei zum Lesen und zum Schreiben mit der Option zum Abschneiden der Datei öffnet. Da es sich immer noch um dieselbe Datei handelt, verlieren Sie den Inhalt. Wenn Sie es jedoch zum Lesen
rm
öffnen und dann denselben Pfadnamen zum Schreiben öffnen, erstellen Sie tatsächlich eine neue Datei mit demselben Pfadnamen (jedoch an einem neuen Inode- und Festplattenspeicherort, da das Original noch geöffnet ist): Also Der Inhalt ist noch verfügbar.Sobald Sie fertig sind, können Sie den zuvor geöffneten Dateideskriptor schließen (dies ist die
exec 3<&-
spezielle Syntax), wodurch die Originaldatei freigegeben wird, sodass das Betriebssystem den Speicherplatz löschen (als nicht verwendet markieren) kann.Vorsichtsmaßnahmen
Bei dieser Lösung sind einige Dinge zu beachten:
Sie erhalten nur ein "Durchgehen" des Inhalts - es gibt keine tragbare Möglichkeit für eine Shell, im Dateideskriptor "zurückzusuchen". Sobald ein Programm einen Teil des Inhalts liest, sehen andere Programme nur den Rest der Datei. Und
sed
liest die gesamte Datei.Es besteht eine geringe Wahrscheinlichkeit, dass Ihre Originaldatei verloren geht, wenn Ihre Shell / Ihr Skript / Ihre Sed getötet wird, bevor sie fertig ist.
quelle
perl -i
ist eine weitere gute Option. Die Frage verlangte speziell eine Lösung, die mit Solaris kompatibel istsed
, im Gegensatz zu Lösungen mitperl
undawk
die sie bereits erwähnt haben. Außerdem sollte meine Antwort hauptsächlich etwas hinzufügen, das ich für nützlich hielt, um es zu wissen und in keiner der anderen Antworten zu vermissen.