SED-Code-Verständnis für die Textverarbeitung

SED-Code-Verständnis für die Textverarbeitung

Könnte mir jemand den folgenden Sed-Code erklären?

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*/\1/
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

Ich möchte die Informationen zum „Richtlinientyp:“ hinzufügen. Wenn ich sie durch „Richtlinienname:“ ersetze, funktioniert es einwandfrei. Wenn ich jedoch einen Abschnitt wie den folgenden hinzufüge, funktioniert es offensichtlich nicht, da ich es versuche, ohne es zu verstehen.

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
/Policy Type:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*/\1/
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

Außerdem habe ich unten aus demselben Forum eine Lösung für einen AIX-äquivalenten Code. Ich muss ihn verstehen, um ihn zu bearbeiten und den Richtlinientyp hinzuzufügen.

# define constants
SPC=`echo x | tr x '\040'`
TAB=`echo x | tr x '\011'`
 NL=

# custom regex for...
s="[$SPC$TAB]";   # horizontal whitespace
S="[^$SPC$TAB]";  # non-whitespace

# POSIX compliant sed code...
sed -ne "
   /Policy Name:/!d

   s/.*:$s\{1,\}//
   h

   :1
      n
      /Active:$s*no/d
   /HW\//!b1

   :2
      s/.*$s\($S*\)$s*/\1/
      G
      s/\n/$TAB/p
      n
      /^$s*\$/d
      /Include:/d
   b2
"  yourfile

Eingabedatei

Policy Name:       Today

  Policy Type:       Standard
  Active:              yes
  Effective date:      01/24/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  EU         NY  Cindy
                 BU         CA  Victor
                 GU         MI  Bob
  Include:
Policy Name:       Tomorrow

  Policy Type:       Oracle
  Active:              yes
  Effective date:      01/26/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  MU         LA  Martha
                 EU         CA  Sam
  Include:
Policy Name:       Yesterday

  Policy Type:       Oracle
  Active:              no
  Effective date:      01/21/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  NV         IL  Joe

  Include:`

Gewünschte Ausgabe

Cindy    Today     Standard
Victor   Today     Standard
Bob      Today     Standard
Martha   Tomorrow  Oracle
Sam      Tomorrow  Oracle

Antwort1

Okay, gehen wir es Schritt für Schritt vor:

sed -n '

Die -nOption gibt sednichts aus, sofern nicht anders angegeben.

/Policy Name:/! d

Alle Zeilen die nicht enthalten Policy name:werden gelöscht. Der Rest des Skripts wird erst in den folgenden Schleifen abgearbeitet.

s/.*:\s\+//
h

Dadurch wird alles bis auf die :Leerzeichen am Ende entfernt und der Rest wird zur späteren Verwendung in den Haltepuffer gelegt.

:1
n

Dies ist der Anfang einer Schleife, die neue Zeilen liest

/Active:\s*no/d

Zeilen mit diesem Muster werden entfernt, daher besteht offensichtlich kein Interesse an inaktiven

/HW\//!b1

Und jetzt führen wir eine Schleife durch, :1wenn die Zeile keineHW/

:2
s/.*\s\(\S*\)\s*/\1/

Entfernen Sie zu Beginn der nächsten Schleife alles außer der letzten Folge von Nicht-Leerzeichen.

G
s/\n/\t/p

Fügen Sie dann den im Hold-Puffer gespeicherten Richtliniennamen durch einen Tabulator getrennt an und drucken Sie diese Zeile aus.

n
/^\s*$\|Include:/! b2
'

und dies wird mit den nächsten Zeilen wiederholt, bis wir das angegebene Muster erreichen.

Sie sollten beachten, dass es sich hierbei um höchst nicht portablen Code handelt, der auf vielen Versionen nicht funktioniert sed.

Bearbeiten:Um den Richtlinientyp als dritte Spalte hinzuzufügen, sollten Sie dem Skript vor oder nach der Active:Prüfung diese Zeile hinzufügen:

/Policy Type:/{s/.*:\s*//;H;}

Das heißt: Wenn die Zeile die besagte Zeichenfolge enthält, führen Sie die Befehle zwischen aus {}. Diese Befehle entfernen den Teil bis zu den :und den nachfolgenden Leerzeichen und hängen den Rest der Zeile (die den Richtlinientyp enthalten soll) an den Hold-Puffer an. Der Hold-Puffer enthält also den Richtliniennamen und -typ, getrennt durch eine neue Zeile. Wenn wir dies also mit anhängen G, müssen zwei neue Zeilen ersetzt werden, sodass der Ersetzungsbefehl das gFlag zum Ersetzen aller Vorkommen erhalten muss:

s/\n/\t/gp

Das AIX-Skript ist im Wesentlichen gleich, vermeidet aber GNU-Erweiterungen für reguläre Ausdrücke. Vor allem die Verwendung von Variablen zum Abgleichen von Leerzeichen oder Tabulatoren, da dies \tnicht in allen Varianten funktioniert sed, sowie +für „eine oder mehrere“ muss ersetzt werden durch\{1,\}

verwandte Informationen