
Ich habe einen Befehl, der Informationen zu allen DIMM-Steckplätzen in Blöcken wie den folgenden ausgibt:
ID SIZE TYPE
44 105 SMB_TYPE_MEMDEVICE (type 17) (memory device)
Manufacturer: NO DIMM
Serial Number: NO DIMM
Asset Tag: NO DIMM
Location Tag: P1-DIMMD1
Part Number: NO DIMM
Physical Memory Array: 43
Memory Error Data: Not Supported
Total Width: 0 bits
Data Width: 0 bits
Size: Not Populated
Form Factor: 9 (DIMM)
Set: None
Rank: Unknown
Memory Type: 2 (unknown)
Flags: 0x4
SMB_MDF_UNKNOWN (unknown)
Speed: Unknown
Configured Speed: Unknown
Device Locator: P1-DIMMD1
Bank Locator: P0_Node1_Channel0_Dimm0
Minimum Voltage: 1.20V
Maximum Voltage: 1.20V
Configured Voltage: 1.20V
Die Blöcke beginnen mit dem ID SIZE TYPE
Header und enden mit den konfigurierten Spannungsinformationen. Der Befehl gibt für jedes DIMM einen dieser Datenblöcke aus, jeweils durch eine einzelne Leerzeile getrennt.
Ich möchte den Informationsblock für einen bestimmten DIMM-Steckplatz basierend auf dem Location Tag
Feld abrufen können, bin mir aber nicht sicher, wie ich das anstellen soll. Ich bin ziemlich sicher, dass dies mit möglich ist, weiß aber nur, wie man die Übereinstimmung oder die Zeile vor der Übereinstimmung awk
drucktawk '/P1-DIMMD1/'
awk '/P1-DIMMD1/ {print a}{a=$0}'
Weiß jemand, wie ich diesen ganzen Datenblock extrahieren kann, wenn er Location Tag
meiner Suche entspricht ( P1-DIMMD1
)?
Antwort1
Folgendes stimmt mit dem in der Tag-Variable angegebenen Tag überein:
awk -v tag=P1-DIMMD1 '/ID SIZE TYPE/ { block = $0; output = 0; next } { block = block "\n" $0 } /Location Tag/ { output = ($0 ~ tag) } /Configured Voltage/ && output { print block }'
Das AWK-Skript ist
/ID SIZE TYPE/ {
block = $0
output = 0
next
}
{ block = block "\n" $0 }
/Location Tag/ { output = ($0 ~ tag) }
/Configured Voltage/ && output { print block }
Wir sammeln einen Block in der block
Variable und geben ihn aus, wenn wir das Ende des Blocks erreichen, sofern wir dabei das richtige Tag gesehen haben.
Antwort2
Sie könntenverwenden ed...Undsed, Mann!
Du musstwollenEs empfiehlt sich jedoch, hierfür ed zu verwenden, da ed mit einer Datei arbeiten möchte und nicht als Teil einer Pipeline.
command > dimm-output
wanted=P1-DIMMD1
ed -s dimm-output <<< $'/Location Tag: '"$wanted"$'\n?^ID.*SIZE.*TYPE\n.,/Configured Voltage/p\nq\n' | sed 1,2d
Die ed
Befehlszeichenfolge gliedert sich in vier \n
durch -getrennte Befehle:
- Suche vorwärts mit
/
nach dem Text "Location Tag: " gefolgt vom Wert der$wanted
Variablen - Suche rückwärts, mit
?
, nach dem Muster: (Zeilenanfang), „ID“, beliebig, „GRÖSSE“, beliebig, „TYP“ - Von dieser Zeile (
.
) bis (,
) zur nächsten Zeile, die mit „Konfigurierte Spannung“ übereinstimmt, drucken Sie diese Zeilen (p
) - beendet:
q
Da ed beim Suchen automatisch die passende Zeile ausgibt, habe ich sed
hier verwendet, um diese beiden Zeilen zu löschen.
Antwort3
Inspiriert von der tollen Antwort von @Stephen Kitts habe ich ein etwas allgemeineres Skript geschrieben, um Blockabgleiche durchzuführen, wenn ein bestimmtes Start- und Endmuster vorliegt.
#!/usr/bin/awk -f
BEGIN {
pstart=ARGV[1];
pstop=ARGV[2];
pmatch=ARGV[3];
ARGV[1]=ARGV[4];
ARGC=2;
}
$0 ~ pstart { block = $0; output = 0; next }
{ block = block "\n" $0 }
$0 ~ pmatch { output = 1 }
$0 ~ pstop && output { print block; output = 0 }
Verwendung:match_block START END MATCH [FILE]
./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1' f
oder
command | ./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1'
Vielen Dank für den Vorschlag, dies direkt als awk
Skript zu schreiben. Mein ursprüngliches Shell-Skript war:
#!/bin/sh
[ -z "$4" ] && file="-" || file="$4"
awk \
-v BLOCKSTART_PATTERN="$1" \
-v BLOCKEND_PATTERN="$2" \
-v BLOCKMATCH_PATTERN="$3" \
'
$0 ~ BLOCKSTART_PATTERN { block = $0; output = 0; next }
{ block = block "\n" $0 }
$0 ~ BLOCKMATCH_PATTERN { output = 1 }
$0 ~ BLOCKEND_PATTERN && output { print block; output = 0 }
' "$file"
Verwendung: match_block START END MATCH [FILE]
Wenn
die Datei weggelassen wird, stdin
wird verwendet.
In Ihrem Fall:
command | ./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1'
oder
./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1' file