
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 -n
Option gibt sed
nichts 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, :1
wenn 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 g
Flag 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 \t
nicht in allen Varianten funktioniert sed
, sowie +
für „eine oder mehrere“ muss ersetzt werden durch\{1,\}