Mit Terminal: Verwenden regulärer Ausdrücke II: Ersetzungen

In meinem vorheriger Artikel Ich habe Ihnen auf einer grundlegenden Ebene erklärt, wie jedes der am häufigsten verwendeten Sonderzeichen regulärer Ausdrücke funktioniert. Mit diesen regulären Ausdrücken ist es möglich, komplexe Suchen in Textdateien oder in der Ausgabe anderer Befehle durchzuführen. In diesem Artikel werde ich erklären, wie Sie mit dem Befehl sed Text viel leistungsfähiger finden und ersetzen können, als nur einen Text durch einen anderen zu ändern.

Ein bisschen mehr über den Befehl grep

Bevor ich über sed spreche, möchte ich noch etwas mehr zum Befehl grep sagen, um das zu vervollständigen, was im vorherigen Artikel erklärt wurde. Alles, was ich sagen werde, wird auch für dieses relevant sein. Später werden wir die Beziehung zwischen diesem und Suchen sehen.

Reguläre Ausdrücke kombinieren

Viele der Sonderzeichen, über die ich im vorherigen Artikel gesprochen habe, können nicht nur mit anderen Zeichen, sondern mit ganzen regulären Ausdrücken kombiniert werden. Der Weg, dies zu tun, besteht darin, Klammern zu verwenden, um einen Unterausdruck zu bilden. Sehen wir uns ein Beispiel dafür an. Beginnen wir mit dem Herunterladen eines Textes, den wir zum Testen verwenden können. Es ist eine Liste von Phrasen. Dafür verwenden wir den folgenden Befehl:

curl http://artigoo.com/lista-de-frases-comparativas-comicas 2>/dev/null | sed -n 's/.*\(.*\.\)<\/p>/\1/gp' > frases

 Dadurch bleiben Sie in dem Verzeichnis, in dem Sie eine Datei mit dem Namen «phrases» starten. Sie können es öffnen, um einen Blick darauf zu werfen und ein wenig zu lachen. 🙂

Nehmen wir nun an, wir möchten die Phrasen finden, die genau 6 Wörter enthalten. Die Schwierigkeit besteht darin, einen regulären Ausdruck zu bilden, der zu jedem Wort passt. Ein Wort ist eine Folge von Buchstaben, entweder in Groß- oder Kleinbuchstaben '[a-zA-Z]+', aber Sie müssen auch angeben, dass diese Buchstaben durch andere Zeichen als Buchstaben getrennt werden müssen, das heißt, es wäre so etwas wie '[a-zA-Z]+[^a-zA-Z]+'. Denken Sie daran: Das "^" als erstes Zeichen in den Klammern zeigt an, dass wir mit Zeichen übereinstimmen möchten, die nicht in den Bereichen liegen, und das "+" gibt 1 oder mehr Zeichen an.

Wir haben bereits einen regulären Ausdruck, der mit einem Wort übereinstimmen kann. Um es mit 6 zu koppeln, muss es 6 Mal wiederholt werden. Dafür haben wir die Schlüssel benutzt, aber es ist sinnlos zu setzen '[a-zA-Z]+[^a-zA-Z]+{6}', weil die 6 den letzten Teil des regulären Ausdrucks wiederholen würde und wir alles wiederholen wollen, müssen wir also Folgendes sagen: '([a-zA-Z]+[^a-zA-Z]+){6}'. Mit den Klammern bilden wir einen Unterausdruck und mit den Klammern wiederholen wir ihn 6 Mal. Jetzt müssen Sie nur noch ein "^" vorne und ein "$" hinten hinzufügen, um der gesamten Zeile zu entsprechen. Der Befehl lautet wie folgt:

grep -E '^([a-zA-Z]+[^a-zA-Z]+){6}$' frases

Und das Ergebnis ist genau das, was wir wollten:

Es wird mehr gesungen als die Macarena. Sie sind mehr fertig als Luis Aguilé. Sie haben weniger Kultur als ein Stein. Sie kennen mehr Sprachen als Cañita Brava. Er hat mehr Falten als Tutan Khamón. Sie wissen weniger als Rambo über Kinderbetreuung.

Beachten Sie, dass wir den Parameter -E einfügen, da wir erweiterte reguläre Ausdrücke verwenden möchten, damit das "+" funktioniert. Wenn wir die grundlegenden verwenden würden, müssten wir uns den Klammern und Klammern entziehen.

Rückverweise oder Rückverweise

Wenn Sie eine Rechtschreibprüfung installiert haben, haben Sie wahrscheinlich eine Liste mit Wörtern in /usr/share/dict/words. Wenn nicht, können Sie es in arch installieren mit:

sudo pacman -S words

Oder in debian mit:

sudo aptitude install dictionaries-common

Wenn Sie möchten, können Sie in der Datei nachsehen, welche Wörter sie enthält. Eigentlich ist es ein Link zur Word-Datei der Sprache, in der sich Ihre Distribution befindet. Sie können mehrere Word-Dateien gleichzeitig installieren.

Wir werden diese Datei verwenden. Es stellt sich heraus, dass wir sehr neugierig sind, alle sieben Buchstabenpalindrome da draußen zu kennen. Für diejenigen, die nicht wissen: Ein Palindrom ist ein Capicúa-Wort, das heißt, es kann sowohl von links nach rechts als auch von rechts nach links gelesen werden. Versuchen wir den folgenden Befehl:

grep '^\(.\)\(.\)\(.\).\3\2\1$' /usr/share/dict/words

Es sieht ein bisschen seltsam aus, oder? Wenn wir es versuchen, hängt das Ergebnis von der Sprache Ihrer Distribution und den Wörtern in Ihrer Liste ab. In meinem Fall lautet das Ergebnis bei der spanischen Sprache jedoch:

Anilin Anilin Rollen

Mal sehen, wie dieser reguläre Ausdruck funktioniert.

Abgesehen von "^" und "$", für die wir bereits wissen, wofür es ist, sehen wir links als erstes drei Gruppen von Punkten in Klammern. Lassen Sie sich nicht durch die Balken vor jeder Klammer verwirren. Sie sollen den Klammern entgehen, weil wir grundlegende reguläre Ausdrücke verwenden, aber sie haben keine andere Bedeutung. Wichtig ist, dass wir nach drei beliebigen Zeichen mit den Punkten fragen, aber jeder dieser Punkte ist in Klammern eingeschlossen. Hiermit werden die Zeichen gespeichert, die diesen Punkten entsprechen, damit sie im regulären Ausdruck erneut referenziert werden können. Dies ist eine weitere Verwendung von Klammern, die später zum Ersetzen nützlich sein wird.

Hier kommen die drei Zahlen unten mit dem Schrägstrich vor sich. In diesem Fall ist die Leiste wichtig. Es wird verwendet, um anzuzeigen, dass die folgende Zahl eine Rückreferenz ist und sich auf eine der vorherigen Klammern bezieht. Zum Beispiel: \ 1 bezieht sich auf die erste Klammer, \ 2 auf die zweite und so weiter.

Das heißt, mit dem regulären Ausdruck, den wir gesetzt haben, suchen wir alle Wörter, die mit vier beliebigen Buchstaben beginnen und dann einen Buchstaben haben, der mit dem dritten identisch ist, einen anderen, der mit dem zweiten identisch ist, und einen anderen das ist das gleiche wie das erste. Das Ergebnis sind die Palindrome mit sieben Buchstaben, die in der Wortliste enthalten sind. Genau wie wir wollten.

Wenn wir erweiterte reguläre Ausdrücke verwenden würden, müssten wir uns nicht den Klammern entziehen, aber mit erweiterten regulären Ausdrücken funktionieren Rückreferenzen nicht in allen Programmen, da sie nicht standardisiert sind. Mit grep funktionieren sie jedoch, sodass dies möglicherweise eine andere Möglichkeit ist, dasselbe zu tun. Sie können es versuchen, wenn Sie wollen.

Ersatzausdrücke: der Befehl sed

Neben der Suche besteht eine der besten Verwendungsmöglichkeiten für reguläre Ausdrücke darin, komplexe Texte zu ersetzen. Eine Möglichkeit hierfür ist der Befehl sed. Die Leistung des Befehls sed geht weit über das Ersetzen von Text hinaus, aber hier werde ich ihn dafür verwenden. Die Syntax, die ich mit diesem Befehl verwenden werde, lautet wie folgt:

sed [-r] 's/REGEX/REPL/g' FICHERO

Oder auch:

COMANDO | sed [-r] 's/REGEX/REPL/g'

Dabei ist REGEX der reguläre Suchausdruck und REPL der Ersatzausdruck. Denken Sie daran, dass dieser Befehl nichts in der von uns angegebenen Datei wirklich ersetzt. Er zeigt uns jedoch das Ergebnis der Ersetzung im Terminal. Lassen Sie sich also nicht von den Befehlen erschrecken, die ich als Nächstes einfügen werde. Keiner von ihnen wird Dateien auf Ihrem System ändern.

Beginnen wir mit einem einfachen Beispiel. Wir haben alle verschiedene Konfigurationsdateien im Verzeichnis / etc, deren Kommentare normalerweise mit "#" beginnen. Angenommen, wir möchten eine dieser Dateien ohne die Kommentare sehen. Zum Beispiel werde ich es mit der fstab machen. Sie können es mit dem gewünschten versuchen.

sed 's/#.*//g' /etc/fstab

Ich werde hier nicht das Ergebnis des Befehls einfügen, da es davon abhängt, was Sie in Ihrer fstab haben. Wenn Sie jedoch die Ausgabe des Befehls mit dem Inhalt der Datei vergleichen, werden Sie feststellen, dass alle Kommentare verschwunden sind.

In diesem Befehl lautet der Suchausdruck «#.*", Das ist ein" # ", gefolgt von einer beliebigen Anzahl von Zeichen, dh den Kommentaren. Wenn Sie sich die beiden Balken in einer Reihe ansehen, werden Sie feststellen, dass es keine gibt. Sie ersetzen also die Kommentare durch nichts, dh löschen sie. Einfacher unmöglich.

Jetzt machen wir das Gegenteil. Angenommen, wir möchten alle Zeilen der Datei kommentieren. Versuchen wir es so:

sed 's/^/# /g' /etc/fstab

Sie werden sehen, dass in der Ausgabe des Befehls alle Zeilen mit einer Raute und einem Leerzeichen beginnen. Wir haben den Zeilenanfang durch «ersetzt# «. Dies ist auch ein ziemlich einfaches Beispiel, bei dem der zu ersetzende Text immer der gleiche ist, aber jetzt werden wir ihn etwas komplizierter machen.

Die Gnade von Ersetzungen besteht darin, dass Sie im Ersetzungsausdruck Rückreferenzen verwenden können, wie ich sie Ihnen zuvor gesagt habe. Kehren wir zu der Phrasendatei zurück, die wir am Anfang des Artikels heruntergeladen haben. Wir werden alle vorhandenen Großbuchstaben in Klammern setzen, aber wir werden es mit einem Befehl tun:

sed 's/\([A-Z]\)/(\1)/g' frases

Was wir hier haben, ist eine Rückreferenz im Ersetzungsausdruck, die sich auf die Klammern im Suchausdruck bezieht. Die Klammern im Ersetzungsausdruck sind normale Klammern. Im Ersatzausdruck haben sie keine besondere Bedeutung, sie werden so wie sie sind gesetzt. Das Ergebnis ist, dass alle Großbuchstaben durch denselben Buchstaben ersetzt werden, unabhängig davon, um was es sich handelt, mit Klammern.

Es gibt ein anderes Zeichen, das auch im Ersetzungsausdruck verwendet werden kann. Es ist "&" und wird durch den gesamten Text ersetzt, der mit dem Suchausdruck übereinstimmt. Ein Beispiel hierfür könnte sein, alle Phrasen in der Datei in Anführungszeichen zu setzen. Dies kann mit diesem Befehl erreicht werden:

sed 's/.*/"&"/g' frases

Die Funktionsweise dieses Befehls ist der vorherigen sehr ähnlich. Erst jetzt ersetzen wir die gesamte Zeile durch dieselbe Zeile mit Anführungszeichen. Da wir "&" verwenden, müssen keine Klammern gesetzt werden.

Einige nützliche Befehle mit regulären Ausdrücken

Hier sind einige Befehle, die ich nützlich oder neugierig finde und die reguläre Ausdrücke verwenden. Mit diesen Befehlen ist die Nützlichkeit regulärer Ausdrücke viel besser als mit den Beispielen, die ich Ihnen bisher gegeben habe, aber es schien wichtig, etwas darüber zu erklären, wie reguläre Ausdrücke funktionieren, um sie zu verstehen.

  • Abschnitte einer Manpage anzeigen:

man bash | grep '^[A-Z][A-Z ]*$'

Natürlich können Sie den Befehl bash nach Belieben ändern. Und dann können Sie vom Menschen direkt zu dem Abschnitt gehen, der Sie interessiert, indem Sie natürlich einen regulären Ausdruck verwenden. Drücken Sie «/», um zu suchen und zu schreiben «^ALIASES$»Zum Beispiel zum Abschnitt ALIASES. Ich denke, dies ist der erste Gebrauch, den ich vor einigen Jahren mit regulären Ausdrücken gemacht habe. Das Durchblättern einiger Seiten des Handbuchs ist ohne einen solchen Trick fast unmöglich.

  • Zeigen Sie die Namen aller Benutzer der Maschine an, einschließlich spezieller:

sed 's/\([^:]*\).*/\1/' /etc/passwd

  • Benutzernamen anzeigen, aber nur solche mit Shell:

grep -vE '(/false|/nologin)$' /etc/passwd | sed 's/\([^:]*\).*/\1/g'

Es kann wirklich mit einem einzigen regulären Ausdruck gemacht werden, aber die Art und Weise, wie es gemacht wird, geht über das hinaus, was ich Ihnen in diesen Artikeln gesagt habe, also habe ich es getan, indem ich zwei Befehle kombiniert habe.

  • Fügen Sie vor den letzten drei Ziffern aller Zahlen in der Zahlendatei ein Komma ein:

sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers

Es funktioniert nur mit Zahlen mit bis zu 6 Ziffern, es kann jedoch mehrmals aufgerufen werden, um Trennzeichen in die anderen dreistelligen Gruppen einzufügen.

  •  Extrahieren Sie alle E-Mail-Adressen aus einer Datei:

grep -E '\<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\>' FICHERO

  • Trennen Sie Tag, Monat und Jahr aller Daten, die in einer Datei angezeigt werden:

sed -r 's/([0-9]{2})[/-]([0-9]{2})[/-]([0-9]{4})/Día: \1, Mes: \2, Año: \3/g' FICHERO

  • Informieren Sie sich über unsere lokale IP:

/sbin/ifconfig | grep 'inet .*broadcast' | sed -r 's/[^0-9]*(([0-9]+\.){3}[0-9]+).*/\1/g'

Dies kann auch mit einem einzelnen sed-Befehl durchgeführt werden, aber ich trenne ihn der Einfachheit halber besser in einen grep und einen sed.

Einige nützliche Adressen

Hier sind einige Adressen, die im Zusammenhang mit regulären Ausdrücken nützlich sein können:

  • Bibliothek für reguläre Ausdrücke: Dies ist eine Bibliothek für reguläre Ausdrücke, in der Sie nach regulären Ausdrücken suchen können, die sich auf das Thema beziehen, das Sie interessiert. Um nach Webadressen, ID oder was auch immer zu suchen.
  • RegExr: Ein Online-Prüfer für reguläre Ausdrücke. Sie können einen Text eingeben und einen regulären Ausdruck darauf anwenden, entweder suchen oder ersetzen. Es gibt Informationen über den regulären Ausdruck und Sie haben einige Möglichkeiten, sein Verhalten zu ändern.
  • Tester für reguläre Ausdrücke: Es ist ein Addon für Firefox, mit dem Sie reguläre Ausdrücke im Browser überprüfen können.

Fazit

Im Moment ist das alles. Reguläre Ausdrücke sind komplex, aber nützlich. Es braucht Zeit, um sie zu lernen, aber wenn Sie wie ich sind, wird es Spaß machen, mit ihnen zu spielen, und nach und nach werden Sie sie beherrschen. Es ist eine ganze Welt. Es gibt noch viel zu sagen über faule Quantifizierer, Regex im PERL-Stil, Multiline usw. Und dann hat jedes Programm seine Eigenschaften und Varianten. Der beste Rat, den ich Ihnen geben kann, ist, immer die Dokumentation des Programms zu lesen, das Sie jedes Mal verwenden, wenn Sie einen regulären Ausdruck in ein neues Programm schreiben müssen.

Hallo! …HALLO! … AUFWACHEN! … WAS SCHLAFEN SIE ALLE? 🙂

Zitate

Einige der Ideen und Beispiele für reguläre Ausdrücke in diesem Artikel habe ich hier übernommen:


Hinterlasse einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert mit *

*

*

  1. Verantwortlich für die Daten: Miguel Ángel Gatón
  2. Zweck der Daten: Kontrolle von SPAM, Kommentarverwaltung.
  3. Legitimation: Ihre Zustimmung
  4. Übermittlung der Daten: Die Daten werden nur durch gesetzliche Verpflichtung an Dritte weitergegeben.
  5. Datenspeicherung: Von Occentus Networks (EU) gehostete Datenbank
  6. Rechte: Sie können Ihre Informationen jederzeit einschränken, wiederherstellen und löschen.

  1.   lebhaft sagte

    Meisterhaft!!!

    1.    Hexborg sagte

      Es ist nicht so schlimm, aber vielen Dank. Hoffe, die Leute mögen es. 🙂

      1.    Oscar sagte

        Ich mag es ha!

        1.    Hexborg sagte

          Dann muss ich etwas richtig gemacht haben. LOL !! 🙂

          Vielen Dank für Ihren Kommentar.

          1.    Blaire pascal sagte

            Verdammt, schreib weiter, Mann, mach weiter so.

          2.    Hexborg sagte

            @Blaire Pascal: Kommentare wie deine ermutigen es. 🙂 Vielen Dank !!

      2.    Stadt sagte

        Mir hat es auch gefallen ... danke 🙂

        1.    Hexborg sagte

          Danke für deinen Kommentar. Ich hoffe noch ein paar zu schreiben. 🙂

  2.   marianisch sagte

    Ihre Beiträge sind fantastisch, Sie lernen viel, Sie lernen vielmehr, Aufgaben auf elegante und effiziente Weise auszuführen.

    Haben Sie darüber nachgedacht, alle Ihre Shell-Skript-Beiträge zu sammeln? In ein PDF sortiert wäre ein großartiges Handbuch.

    Aufmunterung und vielen Dank!

    1.    Hexborg sagte

      Vielen Dank!! Das ist keine schlechte Idee. Im Moment gibt es nur zwei, aber ich werde später darüber nachdenken. 🙂

  3.   Kijow sagte

    sehr guter Artikel, 5+.

    1.    Hexborg sagte

      Vielen Dank. Ich freu mich, dass es dir gefällt. 🙂

  4.   Sebastian sagte

    Ausgezeichnet! Ich muss den folgenden Ausdruck ändern und weiß nicht, wie ich das machen soll:
    192.168.0.138/Server von 192.168.0.111/data
    Das Problem liegt im Symbol "/".
    Ich benutze den Befehl:
    finden. -name "* .txt" -exec sed -i 's / TEXT1 / TEXT2 / g' {} \;
    Was wird verwendet, um diese Art von Aufgabe nachlässig auszuführen, aber ich kann nicht ...
    Weiß jemand, wie ich es machen soll?
    Umarmung!
    Seba

    1.    Hexborg sagte

      Was Sie tun müssen, ist dem Charakter wie folgt zu entkommen:

      finden. -name "* .txt" -exec sed -is / \ / Server / \ / data / g '{} \;

      Sie können auch ein anderes Trennzeichen in sed verwenden. Es muss keine Bar sein. Mit Sed kann jeder Charakter verwendet werden. Zum Beispiel wäre dies klarer:

      finden. -name "* .txt" -exec sed -is | / Server | / data | g '{} \;

      Und wenn Sie die Befehle aus diesem Kommentar kopieren und einfügen möchten, achten Sie auf die Anführungszeichen, damit WordPress sie durch die typografischen ändert. 🙂

      Grüße.

  5.   Sebastian sagte

    Ausgezeichnet!
    Ich habe lange nach dieser Lösung gesucht.
    Hier lasse ich den vollständigen Befehl, den ich verwendet habe

    finden. -name "* .txt" -exec sed -i 's | 192 \ .168 \ .0 \ .238 \ / Server | 192 \ .168 \ .0 \ .111 \ / data | g' {} \;

    Der Vorteil dieses Befehls ist, dass er alle TXT-Dateien (oder die gewünschte Erweiterung) rekursiv ändert ... Sie müssen sehr vorsichtig sein!
    Aber es ist sehr nützlich !!!

    Vielen Dank für alles und tausend Glückwünsche an die gesamte Gruppe.
    Ich habe sie immer aus der Post gelesen!
    Umarmungen
    Seba