GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bearbeiten von Text auf der Kommandozeile mit sed

In einem früheren Artikel habe ich behandelt, wie man Text mit grep manipuliert . Wenden Sie sich nun dem sed zu (Stream-Editor), der sich am besten für die Verwendung in Pipelines eignet (Daten, die aus einer Pipe stammen). Der sed kann verwendet werden, um den Inhalt einer Datei zu drucken, eine Zeile (oder mehrere Zeilen) zu ersetzen und dann die Datei zu speichern. Im Gegensatz zu grep , sed kann eine Zeile oder mehrere Zeilen in einer Datei ersetzen und einen in-place durchführen Update dieser Datei.

Das einfachste sed Aufruf beim Ersetzen von foo für bar ist:

$ sed 's/foo/bar/' inputfile

Beispiel:Kommentare entfernen

Während grep Ausgabe auf dem Bildschirm formatieren kann, ist es nicht möglich, eine Datei an Ort und Stelle zu ändern. Dazu benötigen Sie einen Dateieditor wie ed . Seit ed nicht Teil dieses Artikels ist, verwenden Sie sed um dasselbe zu erreichen wie mit grep im ersten Beispiel des vorherigen Artikels. Ändern Sie dieses Mal die /etc/fstab Datei an Ort und Stelle, indem Sie den -i übergeben Flag zu sed . Ohne das -i flag , würden Sie nur sehen, was geändert worden wäre.

Es wird empfohlen, immer sed auszuführen ohne das -i Flag, nur um sicherzustellen, dass das Ergebnis, das es erzeugt, erwartet wird. Der sed Utility bietet auch das -i.bak Flag, das vor der Bearbeitung eine Sicherungsdatei erstellt.

Das letzte grep Befehl für dieses Beispiel war:

$ grep -v '^#' /etc/fstab > ~/fstab_without_comment

Mit sed , haben Sie:

# sed -i '/^#/d' /etc/fstab

/dev/mapper/VGCRYPTO-ROOT /                       ext4    defaults,x-systemd.device-timeout=0 1 1
UUID=e9de0f73-ddddd-4d45-a9ba-1ffffa /boot                   ext4    defaults             1 2
LABEL=SSD_SWAP		swap		swap		defaults	0 0

Beispiel:Nur /etc/passwd drucken Benutzer

Im grep Beispiel:Sie haben nur Nutzernamen aus /etc/passwd gedruckt Datei mit folgendem:

$ grep -Eo '^[a-zA-Z_-]+' /etc/passwd

Sie können dasselbe mit sed tun wie folgt:

$ sed 's/^\([a-zA-Z_-]\+\).*/\1/' /etc/passwd

Im obigen Beispiel gruppieren Sie eine Übereinstimmung durch Klammern () , und drucken Sie dann die übereinstimmende Gruppe mit \1 (Rückverweis), die die erste Gruppe diktiert. Für eine zweite Gruppe würden Sie \2 verwenden , und so weiter.

Beispiel:Ersetzen Sie alle foo mit bar

In sed können Sie nach einem Muster suchen und dann nur das Vorkommen ersetzen, das dem Muster entspricht. Um alle Vorkommen in der Datei inputfile1 zu ersetzen von foo zu bar Führen Sie global Folgendes aus:

$ sed -i '/foo/bar/g' inputfile1

Beispiel:Ersetzen einer einzelnen Instanz

Nehmen Sie die Datei inputfile2 , die folgenden Inhalt hat:

hello world
second line should be replaced
this line should be replaced later

Angenommen, Sie möchten should ersetzen mit will , aber nur für die zweite Zeile. Dieser Befehl gliedert sich wie folgt:

$ sed '/second/s/should/will/' inputfile2
          |    |    |     |
          |    |    |     with this pattern 
          |    |    this pattern
          |    substitute   
         Search for the pattern "second"

Diese Ausgabe wird an die Standardausgabe gesendet, anstatt den Inhalt der Datei zu ersetzen. Das Ergebnis sieht so aus:

$ sed '/second/s/should/will/' inputfile2
hello world
second line will be replaced
this line should be replaced later

Der sed Beim Befehl wird zwischen Groß- und Kleinschreibung unterschieden. Folgendes funktioniert nicht, wenn Sie versuchen, World zu ersetzen mit there :

$ echo "Hello World" | sed 's/world/there/'
Hello World

GNU sed führte ein neues Flag ein, /I , die Groß- und Kleinschreibung ignoriert und wird Führen Sie die Ersetzung mit demselben Befehl durch:

$ echo "Hello World" | sed 's/world/there/I'
Hello there

Beispiel:Einen Zeilenbereich drucken und beenden

Mit sed , können Sie auch Zeilen drucken und beenden, nachdem Ihre Kriterien erfüllt sind. Die folgenden Befehle drucken drei Zeilen und beenden sich. Dieser Befehl:

$ sed -n '1,3p' /etc/passwd

entspricht:

$ sed '3q' /etc/passwd

Folgendes wäre falsch:

$ sed '1,3q' /etc/passwd # Wrong. You cannot quit three times 

Beispiel:Kommentieren Sie unkommentierte Zeilen aus

Reguläre Ausdrücke können auch mit sed verwendet werden , wie zuvor gezeigt. Sie haben beispielsweise das folgende kleine Skript:

$ cat test_script 
#/usr/bin/env bash

this is the first comment
This is another comment
# this is a comment too

echo "This is not a comment and should be echoed"

Sie müssen jetzt die erste Zeile überspringen, beginnend mit #!/bin/bash , und kommentieren Sie die dritte und vierte Zeile aus, aber nicht die fünfte, da diese Zeile bereits auskommentiert ist.

In sed , können Sie Folgendes verwenden:

$ sed '3,6s/^[^#]/# &/g' test_script
#/usr/bin/env bash

# this is the first comment
# This is another comment
# this is a comment too

echo "This is not a comment and should be echoed"

Im obigen Befehl wird Folgendes ausgeführt:

  • 3,6s  definiert einen Bereich von Zeile drei bis Zeile sechs.
  • /^[^#]/ entspricht allem, was ein Zeichen ist und nicht mit einem Hash beginnt (# ).
  • /# &/g ersetzt einen Teil, in diesem Fall setzt es ein # vor der durch & vorgegebenen Zeile unterschreiben.

Beispiel:Alle Ziffern entfernen

Verschiedene Anwendungen erzeugen Daten in unterschiedlichen Formaten. Mit sed , können Sie nur die Daten behalten, die Sie verwenden können. Sie haben beispielsweise die folgende Datei (inputfile3 ) in diesem Format:

foo1234
bar99128
baz2842
qux12953
discard39120

Vielleicht hat ein Programm das falsche Format generiert oder die Felder zu einem verkettet. Was wäre, wenn Sie nur die Buchstaben behalten und die Ziffern verwerfen möchten? Wie würden Sie dieses Ziel mit sed erreichen ?

Die Antwort ist wahrscheinlich einfacher als Sie denken:

$ sed 's/\([a-z]*\).*/\1/' inputfile3
foo
bar
baz
qux
discard

Beispiel:Bestimmte Zeilen ändern

Außerdem sed kann Bereiche auch nach Muster handhaben, was bedeutet, dass Sie einen Start angeben können und ein Ende Zeichenfolge und manipulieren Sie den Bereich. Zum Beispiel:

$ cat inputfile4

hello world

start of the comment
another comment
end of a comment

dont comment this line
nor this line

Der folgende sed Der Befehl kommentiert Zeilen, die mit start beginnen und endet mit end :

$ sed '/start/,/end/ s/^/# /' inputfile4 
hello world

# start of the comment
# another comment
# end of a comment

dont comment this line
nor this line

Entfernen Sie auch die leeren Zeilen.

$ sed '/start/,/end/ s/^/# /;/^$/d' inputfile4

hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line

sed bietet noch viel mehr und seine reichhaltigen Funktionen. Um sed vollständig nutzen zu können Die Fähigkeiten von finden Sie auf der Dokumentationsseite, die Sie hier finden können. Auch eine großartige Informationsquelle zu sed finden Sie hier.

Zusammenfassung

Wie ich bereits erwähnt habe, verwenden Sie grep wenn Sie nach einem Muster suchen möchten, entweder in einer Datei oder mehreren Verzeichnissen rekursiv. Verwenden Sie sed wenn Sie Daten von einer Pipeline empfangen oder Daten spontan manipulieren möchten.

Der sed Der Befehl ist skriptbasiert und es ist leicht zu erlernen, grundlegende Operationen auszuführen. Alles, was Sie brauchen, ist Übung, insbesondere mit regulären Ausdrücken.


Linux
  1. Ersetzen Sie intelligente Anführungszeichen durch den Linux-Befehl sed

  2. Lernen Sie, den Sed-Texteditor zu verwenden

  3. Lassen Sie sich mit sort in der Befehlszeile sortieren

  4. Arbeiten mit Datenströmen auf der Linux-Befehlszeile

  5. Multitasking auf der Kommandozeile mit Screenie

So verwenden Sie Nano, den Linux-Befehlszeilen-Texteditor

Meistern Sie die Linux-Befehlszeile

Bearbeiten von Text mit sed und grep

Bearbeiten von Text in der Befehlszeile mit grep

Zeiterfassung mit Timewarrior auf der Kommandozeile

Verwendung des Linux-Befehls sed mit Beispielen