Bash awk/sed extrahiert mithilfe von Schlüsselwörtern mehrere Zeichenfolgen aus einer einzigen großen Zeichenfolge

Bash awk/sed extrahiert mithilfe von Schlüsselwörtern mehrere Zeichenfolgen aus einer einzigen großen Zeichenfolge

Bitte helfen Sie mir herauszufinden, wie ich mehrere Teilzeichenfolgen basierend auf Schlüsselwörtern extrahieren kann. Ich habe mit verschiedenen Methoden mit Trennzeichen zu kämpfen

Mein Input:

Inventory for 30844-ap01 NAME: AP1800 , DESCR: Cisco Aironet 1800 Series (IEEE 802.11ac) Access Point PID: AIR-AP1832I-E-K9, VID: V03, SN: KWC21420CKU
Inventory for ckh.hq-ap99 NAME: AP2700 , DESCR: Cisco Aironet 2700 Series (IEEE 802.11n) Access Point PID: AIR-CAP2702I-E-K9, VID: V03, SN: FCW2007N0ZQ
Inventory for AP0042.6843.ab78 NAME:  , DESCR:  PID: AIR-CAP1702I-E-K9, VID: V, SN: FCZ201622NY

Gewünschte Ausgabe:

30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

Die erste Zeichenfolge ist irgendetwas zwischen „Inventar für“ und dem nächsten Leerzeichen

Die zweite Zeichenfolge ist alles zwischen "PID: " und dem Komma

Die dritte Zeichenfolge ist eine 11-stellige Zeichenfolge nach „SN:“

Antwort1

Verwenden eines beliebigen sed in einer beliebigen Shell auf jeder Unix-Box:

$ sed 's/Inventory for \([^ ]*\).*PID: \([^,]*\).*SN:/\1 \2/' file
30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

Antwort2

Ich denke, das beste Tool für solche Aufgaben verfügt grepüber folgende PCREFunktionen:

grep -Po '(?<=Inventory for )[^ ]+|(?<=PID: )[^,]+|(?<=SN: ).{11}' data

Dies hat jedoch den Nachteil, dass jeder Treffer in einer separaten Zeile gedruckt wird:

30844-ap01
AIR-AP1832I-E-K9
KWC21420CKU
ckh.hq-ap99
AIR-CAP2702I-E-K9
FCW2007N0ZQ
AP0042.6843.ab78
AIR-CAP1702I-E-K9
FCZ201622NY

Wechseln wir also zu perlund machen dasselbe:

perl -lne ' $i = $& if /(?<=Inventory for )[^ ]+/; $p = $& if /(?<=PID: )[^,]+/ ; $s = $& if /(?<=SN: ).{11}/; print join " ", $i, $p, $s' data

Drucken:

30844-ap01 AIR-AP1832I-E-K9 KWC21420CKU
ckh.hq-ap99 AIR-CAP2702I-E-K9 FCW2007N0ZQ
AP0042.6843.ab78 AIR-CAP1702I-E-K9 FCZ201622NY

Antwort3

Verwendung von gawk:

awk '{a=b=c=$0;
gsub(/^.*Inventory for | .*$/,"",a);
gsub(/^.*PID: |,.*$/, "",b);
sub(/^.*SN: /,"",c); c=substr(c,1,11);
print a,b,c}' input

Die ersten drei Variablen a, bund cwerden auf den aktuellen Eingabedatensatz () gesetzt . Dann ändert $0die integrierte Funktion den regulären Ausdruck in einen leeren Ausdruck ( ). Der reguläre Ausdruck verwendet hier Alternation und hat zwei Muster und . Alternation ermöglicht alternative Muster in regulären Ausdrücken mit . Mit von Zeilenanfang( ) nach wird in geändert . Das bedeutet, dass alle Zeichen vom Zeilenanfang bis zum ersten gewünschten String entfernt werden. Ebenso wird vom Leerzeichen (nach dem ersten gewünschten String) bis zum Zeilenende in geändert . Ebenso hat es zwei alternative Muster und . Beide werden in geändert .gsub()""(/^.*Inventory for | .*$//^.*Inventory for // .*$/|gsub()^Inventory for""""/^.*PID: |,.*$//^.*PID: //,.*$/""

Als Nächstes wird in eine leere Zeichenfolge sub()gewechselt und die 11 Zeichen lange Zeichenfolge wird von übernommen ./^.*SN: /substr(c,1,11)c

verwandte Informationen