Einführung
Der Befehl sed
, kurz für stream editor, führt Bearbeitungsvorgänge für Text aus Standardeingaben oder einer Datei durch. sed
bearbeitet Zeile für Zeile und nicht interaktiv.
Dies bedeutet, dass Sie beim Aufrufen des Befehls alle Bearbeitungsentscheidungen treffen und sed
die Anweisungen automatisch ausführt., Dies mag verwirrend oder nicht intuitiv erscheinen, ist jedoch eine sehr leistungsstarke und schnelle Möglichkeit, Text zu transformieren, insbesondere als Teil eines Skripts oder eines automatisierten Workflows.
Dieses Tutorial behandelt einige grundlegende Vorgänge und führt Sie in die Syntax ein, die für die Bedienung dieses Editors erforderlich ist. Sie werden Ihren regulären Texteditor mit ziemlicher Sicherheit nie durch sed
ersetzen, aber es wird wahrscheinlich eine willkommene Ergänzung zu Ihrer Textbearbeitungs-Toolbox werden.
Hinweis:Dieses Tutorial verwendet die GNU-Version von sed
auf Ubuntu und anderen Linux-Betriebssystemen., Wenn Sie macOS verwenden, haben Sie die BSD-Version mit verschiedenen Optionen und Argumenten. Sie können die GNU-Version von sed
mit Homebrew mit brew install gnu-sed
installieren.
Grundlegende Verwendung
sed
arbeitet mit einem Textstrom, den er entweder aus einer Textdatei oder aus einer Standardeingabe (STDIN) liest. Dies bedeutet, dass Sie die Ausgabe eines anderen Befehls zur Bearbeitung direkt an sed senden oder an einer bereits erstellten Datei arbeiten können.,
Sie sollten sich auch bewusst sein, dass sed
standardmäßig alles in standard out (STDOUT) ausgibt. Das bedeutet, dass sed
, sofern nicht umgeleitet, seine Ausgabe auf dem Bildschirm druckt, anstatt sie in einer Datei zu speichern.
Die grundlegende Verwendung ist:
- sed commands
In diesem Tutorial verwenden Sie eine Kopie der BSD-Softwarelizenz, um mit sed
zu experimentieren., Führen Sie unter Ubuntu die folgenden Befehle aus, um die BSD-Lizenzdatei in Ihr Home-Verzeichnis zu kopieren, damit Sie damit arbeiten können:
- cd
- cp /usr/share/common-licenses/BSD .
Wenn Sie keine lokale Kopie der BSD-Lizenz haben, erstellen Sie selbst eine mit diesem Befehl:
- cat << 'EOF' > BSD
- Copyright (c) The Regents of the University of California.
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- EOF
Verwenden Sie sed
, um den Inhalt der BSD-Lizenzdatei anzuzeigen. sed
sendet seine Ergebnisse standardmäßig an den Bildschirm, was bedeutet, dass Sie ihn als Dateileser verwenden können, indem Sie ihm keine Bearbeitungsbefehle übergeben., Versuchen Sie, den folgenden Befehl auszuführen:
- sed '' BSD
Auf dem Bildschirm wird die BSD-Lizenz angezeigt:
OutputCopyright (c) The Regents of the University of California.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.......
Die einfachen Anführungszeichen enthalten die Bearbeitungsbefehle, die Sie an sed
übergeben. In diesem Fall haben Sie nichts übergeben, daher hat sed
jede empfangene Zeile in die Standardausgabe gedruckt.
sed
kann Standardeingabe anstelle einer Datei verwenden., Leiten Sie die Ausgabe des Befehls cat
in sed
um das gleiche Ergebnis zu erzielen:
- cat BSD | sed ''
Sie sehen die Ausgabe der Datei:
OutputCopyright (c) The Regents of the University of California.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.. . .. . .
Wie Sie sehen, können Sie Dateien oder Textströme bearbeiten, wie die beim Weiterleiten der Ausgabe mit
(|)
Zeichen, genauso einfach.
Druckzeilen
Im vorherigen Beispiel haben Sie gesehen,dass die Eingabe, die an sed
ohne Operationen übergeben wurde, die Ergebnisse direkt an die Standardausgabe ausgibt.,
Lassen Sie uns sed
’s explizite print
Befehl, den Sie angeben, indem Sie die p
Zeichen in einfachen Anführungszeichen.
Führen Sie den folgenden Befehl aus:
- sed 'p' BSD
Sie sehen jede Zeile der BSD
Datei, die zweimal gedruckt wird:
OutputCopyright (c) The Regents of the University of California.Copyright (c) The Regents of the University of California.All rights reserved.All rights reserved.Redistribution and use in source and binary forms, with or withoutRedistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsmodification, are permitted provided that the following conditionsare met:are met:. . .. . .
sed
druckt standardmäßig automatisch jede Zeile, und Sie haben ihr dann gesagt, dass Sie Zeilen explizit mit der „p“ Befehl, so erhalten Sie jede Zeile zweimal gedruckt.,
Wenn Sie die Ausgabe genau untersuchen, werden Sie sehen, dass sie zweimal die erste Zeile hat, gefolgt von der zweiten Zeile zweimal usw., was Ihnen sagt, dass sed
auf Daten arbeitet Zeile für Zeile. Es liest eine Zeile, arbeitet daran und gibt den resultierenden Text aus, bevor der Vorgang in der nächsten Zeile wiederholt wird.
Sie können die Ergebnisse bereinigen, indem Sie die Option -n
an sed
übergeben, wodurch das automatische Drucken unterdrückt wird:
- sed -n 'p' BSD
OutputCopyright (c) The Regents of the University of California.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.. . .. . .
Wir drucken jetzt jede Zeile einmal aus.,
Die bisherigen Beispiele können kaum als bearbeitet betrachtet werden (es sei denn, Sie wollten jede Zeile zweimal drucken…). Als nächstes erfahren Sie, wie sed
die Ausgabe ändern kann, indem Sie auf bestimmte Abschnitte der Textdaten abzielen.
Mit Adressbereichen
Adressen können Sie bestimmte Teile eines Textstroms anvisieren. Sie können eine bestimmte Zeile oder sogar einen Zeilenbereich angeben.
Lassen Sie uns sed
die erste Zeile der Datei drucken., Führen Sie den folgenden Befehl aus:
- sed -n '1p' BSD
Die erste Zeile wird auf dem Bildschirm gedruckt:
OutputCopyright (c) The Regents of the University of California.
Indem Sie die Nummer 1
vor dem Druckbefehl haben Sie sed
die zu bedienende Zeilennummer angegeben. Sie können genauso einfach fünf Zeilen drucken (vergessen Sie nicht das „-n“):
- sed -n '1,5p' BSD
Sie sehen diese Ausgabe:
OutputCopyright (c) The Regents of the University of California.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditions
Sie haben gerade einen Adressbereich für sed
angegeben., Wenn Sie sed
eine Adresse geben, werden nur die Befehle ausgeführt, die in diesen Zeilen folgen. In diesem Beispiel haben Sie sed angewiesen, Zeile 1 bis Zeile 5 zu drucken. Sie hätten dies auf andere Weise angeben können, indem Sie die erste Adresse angegeben und dann einen Offset verwendet haben, um sed mitzuteilen, wie viele zusätzliche Zeilen wie folgt verschoben werden sollen:
- sed -n '1,+4p' BSD
Dies führt zur gleichen Ausgabe, da Sie sed
haben, um in Zeile 1 zu beginnen und dann auch in den nächsten 4 Zeilen zu arbeiten.,
Wenn Sie jede andere Zeile drucken möchten, geben Sie das Intervall nach dem Zeichen ~
an. Der folgende Befehl gibt jede andere Zeile in der Datei BSD
aus, beginnend mit Zeile 1:
- sed -n '1~2p' BSD
Hier sehen Sie die Ausgabe:
OutputCopyright (c) The Regents of the University of California.modification, are permitted provided that the following conditions1. Redistributions of source code must retain the above copyright2. Redistributions in binary form must reproduce the above copyright documentation and/or other materials provided with the distribution. may be used to endorse or promote products derived from this software. . .. . .
Sie können auch sed
verwenden, um Text aus der Ausgabe zu löschen.,
Text löschen
Sie können das Löschen von Text dort durchführen, wo Sie zuvor Textdruck angegeben haben, indem Sie den Befehl p
in den Befehl d
ändern.
In diesem Fall benötigen Sie den Befehl -n
nicht mehr, da sed
alles druckt, was nicht gelöscht wird. Dies wird Ihnen helfen zu sehen, was Los ist.,
Ändern Sie den letzten Befehl aus dem vorherigen Abschnitt zu machen,
löschen Sie jede andere Zeile, beginnend mit der ersten:
- sed '1~2d' BSD
Das Ergebnis ist, dass Sie sehen, jede Zeile, die Sie waren nicht gegeben, letzten Zeit:
OutputAll rights reserved.Redistribution and use in source and binary forms, with or withoutare met: notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the3. Neither the name of the University nor the names of its contributors without specific prior written permission.. . .. . .
Es ist wichtig, hier zu beachten, dass unsere Quelle Datei ist nicht betroffen. Es ist noch intakt. Die Änderungen werden auf unserem Bildschirm ausgegeben.,
Wenn wir unsere Änderungen speichern möchten, können wir die Standardausgabe wie folgt in eine Datei umleiten:
- sed '1~2d' BSD > everyother.txt
Öffnen Sie nun die Datei mit cat
:
- cat everyother.txt
Sie sehen dieselbe Ausgabe, die Sie zuvor auf dem Bildschirm gesehen haben:
OutputAll rights reserved.Redistribution and use in source and binary forms, with or withoutare met: notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the3. Neither the name of the University nor the names of its contributors without specific prior written permission.. . .. . .
Der Befehl sed
bearbeitet die Quelldatei nicht standardmäßig, Sie können dieses Verhalten jedoch ändern, indem Sie die Option -i
übergeben, was „Änderungen an Ort und Stelle ausführen“ bedeutet.“Dadurch wird die Quelldatei geändert.,
Warnung: Wenn Sie den Schalter -i
verwenden, wird die Originaldatei überschrieben. Führen Sie die Operationen ohne den Schalter -i
aus und führen Sie den Befehl dann erneut mit -i
Sobald Sie haben, was Sie wollen, erstellen Sie eine Sicherungskopie der Originaldatei oder leiten Sie die Ausgabe in eine Datei um. Es ist sehr einfach, die Originaldatei versehentlich mit dem Schalter -i
zu ändern.
Versuchen wir es, indem wir die soeben erstellteeveryother.txt
-Datei bearbeiten., Lassen Sie uns die Datei weiter reduzieren, indem Sie jede andere Zeile
erneut löschen:
- sed -i '1~2d' everyother.txt
Wenn Sie cat
verwenden, um die Datei mit cat everyother.txt
anzuzeigen, sehen Sie, dass die Datei bearbeitet wurde.
-i
– option kann gefährlich sein. Zum Glück können Sie mit sed
vor der Bearbeitung eine Sicherungsdatei erstellen.,
Um eine Sicherungsdatei vor der Bearbeitung zu erstellen, fügen Sie die Sicherungserweiterung direkt nach der Option „-i“ hinzu:
- sed -i.bak '1~2d' everyother.txt
Dadurch wird eine Sicherungsdatei mit der Erweiterung .bak
erstellt und die Originaldatei an Ort und Stelle bearbeitet.
Als nächstes sehen Sie sich an, wie Sie sed
verwenden, um Such-und Ersetzungsvorgänge auszuführen.
Text ersetzen
Vielleicht ist die bekannteste Verwendung für sed
Text ersetzen., sed
kann mit regulären Ausdrücken nach Textmustern suchen und dann den gefundenen Text durch etwas anderes ersetzen.
Sie können mehr über reguläre Ausdrücke erfahren, indem Sie den regulären Grep-Ausdrücken folgen, um unter Linux nach Textmustern zu suchen.
In seiner grundlegendsten Form können Sie ein Wort mit der folgenden Syntax in ein anderes Wort ändern:
's/old_word/new_word/'
Die s
ist der Ersatzbefehl. Die drei Schrägstriche (/
) werden verwendet, um die verschiedenen Textfelder zu trennen., Sie können andere Zeichen verwenden, um die Felder abzugrenzen, wenn dies hilfreicher wäre.
Wenn Sie beispielsweise versuchen, einen Website-Namen zu ändern, ist die Verwendung eines anderen Trennzeichens hilfreich, da URLs Schrägstriche enthalten.
Führen Sie den folgenden Befehl aus, um eine URL mit echo
zu drucken, und ändern Sie sie mit sed
unter Verwendung des Unterstrichs (_
) Zeichen als Trennzeichen:
- echo "http://www.example.com/index.html" | sed 's_com/index_org/home_'
Dies ersetzt com/index
mit org/home
., Die Ausgabe zeigt die geänderte URL:
Output
Do not forget the final delimiter, or sed
will complain. If you ran this command:
- echo "http://www.example.com/index.html" | sed 's_com/index_org/home'
Sie würden diese Ausgabe sehen:
Outputsed: -e expression #1, char 20: unterminated `s' command
Lassen Sie uns eine neue Datei erstellen, um einige Ersetzungen zu üben. Führen Sie den folgenden Befehl aus, um eine neue Textdatei mit dem Namen song.txt
zu erstellen:
- echo "this is the song that never ends
- yes, it goes on and on, my friend
- some people started singing it
- not knowing what it was
- and they'll continue singing it forever
- just because..." > song.txt
Ersetzen wir nun den Ausdruck on
durch forward
. Verwenden Sie den folgenden Befehl:
- sed 's/on/forward/' song.txt
Die Ausgabe sieht folgendermaßen aus:
Outputthis is the sforwardg that never endsyes, it goes forward and on, my friendsome people started singing itnot knowing what it wasand they'll cforwardtinue singing it foreverjust because...
Hier sehen Sie einige bemerkenswerte Dinge., Erstens ist, dass sed
Muster ersetzt, keine Wörter. Die on
innerhalb von song
wird in forward
geändert.
Das andere, was zu beachten ist, ist, dass in Zeile 2 die zweite on
nicht in forward
geändert wurde.
Dies liegt daran, dass standardmäßig der Befehl s
für die erste Übereinstimmung in einer Zeile ausgeführt wird und dann zur nächsten Zeile wechselt., Damit sed
jede Instanz von on
anstelle der ersten in jeder Zeile ersetzt, müssen Sie ein optionales Flag an den Ersatzbefehl übergeben.
Geben Sie das Flag g
an den Ersatzbefehl an, indem Sie es nach dem Substitutionssatz platzieren:
- sed 's/on/forward/g' song.txt
Sie sehen diese Ausgabe:
Outputthis is the sforwardg that never endsyes, it goes forward and forward, my friendsome people started singing itnot knowing what it wasand they'll cforwardtinue singing it foreverjust because...
Jetzt ändert der Ersatzbefehl jede Instanz.,
Wenn Sie nur die zweite Instanz von „on“ ändern möchten, die sed in jeder Zeile findet, verwenden Sie die Nummer 2
anstelle der g
:
- sed 's/on/forward/2' song.txt
Diesmal sind die anderen Zeilen unverändert, da sie kein zweites Vorkommen haben:
Outputthis is the song that never endsyes, it goes on and forward, my friendsome people started singing itnot knowing what it wasand they'll continue singing it foreverjust because...
Wenn Sie nur sehen möchten, welche Zeilen ersetzt wurden, verwenden Sie erneut die Option -n
, um den automatischen Druck zu unterdrücken.,
Sie können dann die Option p
an den Befehl substitute übergeben, um Zeilen zu drucken, in denen die Substitution stattgefunden hat.
- sed -n 's/on/forward/2p' song.txt
Die Zeile, die sich geändert hat, wird auf dem Bildschirm gedruckt:
Outputyes, it goes on and forward, my friend
Wie Sie sehen, können Sie die Flags am Ende des Befehls kombinieren.
Wenn Sie möchten, dass der Suchprozess den Groß-und Kleinschreibung ignoriert, können Sie ihm das Flag „i“ übergeben.,
- sed 's/SINGING/saying/i' song.txt
Hier ist die Ausgabe, die Sie sehen werden:
Outputthis is the song that never endsyes, it goes on and on, my friendsome people started saying itnot knowing what it wasand they'll continue saying it foreverjust because...
Ersetzen und Referenzieren von übereinstimmendem Text
Wenn Sie komplexere Muster mit regulären Ausdrücken finden möchten, haben Sie eine Reihe verschiedener Methoden zum Referenzieren des übereinstimmenden Musters im Ersetzungstext.,
Um beispielsweise vom Zeilenanfang an at
abzugleichen, verwenden Sie den folgenden Befehl:
- sed 's/^.*at/REPLACED/' song.txt
Sie sehen diese Ausgabe:
Output REPLACED never endsyes, it goes on and on, my friendsome people started singing itREPLACED it wasand they'll continue singing it foreverjust because...
Sie können sehen, dass der Platzhalterausdruck vom Zeilenanfang bis zur letzten Instanz von at
.
Da Sie den genauen Ausdruck, der in der Suchzeichenfolge übereinstimmt, nicht kennen, können Sie das Zeichen &
verwenden, um den übereinstimmenden Text in der Ersetzungszeichenfolge darzustellen.,
Setzen wir Klammern um den übereinstimmenden Text:
- sed 's/^.*at/(&)/' song.txt
Sie sehen diese Ausgabe:
Output (this is the song that) never endsyes, it goes on and on, my friendsome people started singing it(not knowing what) it wasand they'll continue singing it foreverjust because...
Eine flexiblere Möglichkeit, auf übereinstimmenden Text zu verweisen, besteht darin, maskierte Klammern zu verwenden, um Abschnitte übereinstimmenden Textes zu gruppieren.
Jede Gruppe von mit Klammern markiertem Suchtext kann durch eine maskierte Referenznummer referenziert werden. Zum Beispiel kann auf die erste Klammern-Gruppe mit \1
verwiesen werden, die zweite mit \2
und so weiter.,
In diesem Beispiel wechseln wir die ersten beiden Wörter jeder Zeile:
- sed 's/\(*\) \(*\)/\2 \1/' song.txt
Sie sehen diese Ausgabe:
Output is this the song that never endsyes, goes it on and on, my friendpeople some started singing itknowing not what it wasthey and'll continue singing it foreverbecause just...
Wie Sie sehen, sind die Ergebnisse nicht perfekt. Zum Beispiel überspringt die zweite Zeile das erste Wort, weil es ein Zeichen hat, das nicht in unserem Zeichensatz aufgeführt ist. Ebenso behandelte es they'll
als zwei Wörter in der fünften Zeile.
Lassen Sie uns den regulären Ausdruck verbessern, um genauer zu sein:
- sed 's/\(*\) \(*\)/\2 \1/' song.txt
Sie werden diese Ausgabe sehen:
Output is this the song that never endsit yes, goes on and on, my friendpeople some started singing itknowing not what it wasthey'll and continue singing it foreverbecause... just
Dies ist viel besser als beim letzten Mal., Dies gruppiert Satzzeichen mit dem zugehörigen Wort.
Beachten Sie, wie wir den Ausdruck in Klammern wiederholen (einmal ohne das Zeichen *
und dann einmal damit). Dies liegt daran, dass das Zeichen *
mit dem Zeichensatz übereinstimmt, der null oder mehrmals davor steht. Dies bedeutet, dass die Übereinstimmung mit dem Platzhalter auch dann als „Übereinstimmung“ betrachtet wird, wenn das Muster nicht gefunden wird.
Um sicherzustellen, dass sed
den Text mindestens einmal findet, müssen Sie ihn einmal ohne Platzhalter abgleichen, bevor Sie den Platzhalter verwenden.,
Fazit
In diesem Tutorial haben Sie den Befehl sed
untersucht. Sie haben bestimmte Zeilen aus der Datei gedruckt, nach Text gesucht, Zeilen gelöscht, die Originaldatei überschrieben und reguläre Ausdrücke verwendet, um Text zu ersetzen. Sie sollten bereits sehen können, wie Sie ein Textdokument mit ordnungsgemäß erstellten sed-Befehlen schnell transformieren können.
Im nächsten Artikel dieser Serie werden Sie einige erweiterte Funktionen erkunden.