Ich habe die folgende Textausgabe von einem Befehl (cmdagent -i), den ich mit awk analysiere:

Component: McAfee Agent  
AgentMode: 1  
Version: 5.0.6.491  
GUID: f0bcc8de-1aa6-00a4-01b9-00505af06706  
TenantId: N/A  
LogLocation: /var/McAfee/agent/logs  
InstallLocation: /opt/McAfee/agent  
CryptoMode: 0  
DataLocation: /var/McAfee/agent  
EpoServerList: 10.0.25.15|epo1|epo1.example.com|10.0.25.20|epo2|epo2.example.com 
EpoPortList: 443  
EpoServerLastUsed: 10.0.25.15  
LastASCTime: N/A  
LastPolicyUpdateTime: 0  
EpoVersion: 5.3.1  
Component: McAfee Agent

Ich möchte in der Zeile, die mit der Zeichenfolge "EpoServerList" beginnt, übereinstimmen und nur die in dieser Zeile enthaltenen IP-Adressen mit nur 1 awk-Befehl drucken.

Wenn ich zwei awk-Befehle verwende, kann ich es zum Laufen bringen, aber ich weiß, dass es mit nur einem ausgeführt werden kann.

Beispielsweise:

# ./cmdagent -i | awk '/^EpoServerList/' | awk -v RS='([0-9]+\\.){3}[0-9]+' 'RT{print RT}'

Welches ergibt die folgende (gewünschte) Ausgabe:

10.0.25.15
10.0.25.20

Ich habe bisher Folgendes versucht:

# ./cmdagent -i | awk -v RS='([0-9]+\\.){3}[0-9]+' '$0 ~ /^EpoServerList/ RT{print RT}'

Welches keine Übereinstimmungen zurückgibt

Und

./cmdagent -i | awk -v RS='([0-9]+\\.){3}[0-9]+' '$0 ~ /^EpoServerList/; RT{print RT}'

Welches gibt die Versionsnummer von einer unerwünschten Zeile zurück:

 5.0.6.491
 10.0.25.15
 10.0.25.20

Und scheint "/ ^ EpoServerList /" nicht zu berücksichtigen, das ich als Kriterium verwenden möchte, um die Zeile mit der Versionszeichenfolge "5.0.6.491" auszuschließen.

Wie kann ich auf EpoServerList übereinstimmen und trotzdem das Datensatztrennzeichen mit dem regulären Ausdruck verwenden, um die IP-Adressen mit nur einer awk-Anweisung abzugleichen und zu drucken?

Dies ist GNU Awk 4.0.2 unter RHEL 7 x86_64 unter Verwendung der Bash-Shell.

0
Chris Smith 18 Jän. 2019 im 21:01

3 Antworten

Beste Antwort

Passen Sie zuerst die Zeilen an und iterieren Sie dann über Felder, die dem IPv4-Muster entsprechen:

awk -F '[|: ]' '/^EpoServerList: / { for (i=1; i<NF; i++) { if (match($i, "([0-9]+\.){3}[0-9]+")) { print $i; } } }'

Durch die Verwendung mehrerer Feldtrennzeichen kann das Etikett als Spalte behandelt und daher beim Abgleichen für IP-Adressen übersprungen werden.

Ich weiß, dass es hier viele gibt, die sagen werden, dass awk> grep + ein anderes Tool, aber ich finde, dass Combo auf einen Blick weitaus mehr Lesbarkeit bietet:

grep '^EpoServerList: ' | grep -oP '([0-9]+\.){3}[0-9]+'

Beachten Sie, dass -o und -p hier GNU-Erweiterungen sind, die ich verwende, weil Sie sich auf RHEL verlassen.

1
bishop 18 Jän. 2019 im 18:40

Sie können diese Perl-Lösung auch ausprobieren

$ perl -lne ' if(/EpoServerList/) { while(/\d+.\d+.\d+.\d+/g) { print "$&" } } ' chris_smith.txt
10.0.25.15
10.0.25.20

Eingang:

$ cat chris_smith.txt
Component: McAfee Agent
AgentMode: 1
Version: 5.0.6.491
GUID: f0bcc8de-1aa6-00a4-01b9-00505af06706
TenantId: N/A
LogLocation: /var/McAfee/agent/logs
InstallLocation: /opt/McAfee/agent
CryptoMode: 0
DataLocation: /var/McAfee/agent
EpoServerList: 10.0.25.15|epo1|epo1.example.com|10.0.25.20|epo2|epo2.example.com
EpoPortList: 443
EpoServerLastUsed: 10.0.25.15
LastASCTime: N/A
LastPolicyUpdateTime: 0
EpoVersion: 5.3.1
Component: McAfee Agent

$
1
stack0114106 19 Jän. 2019 im 02:25
awk -F'[ |]' '/EpoServerList/{print $2"\n"$5}' file
10.0.25.15
10.0.25.20
0
Claes Wikner 18 Jän. 2019 im 20:09