
Tengo un comando que genera información sobre todas las ranuras DIMM en bloques como el siguiente:
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
Los bloques comienzan con el ID SIZE TYPE
encabezado y terminan con la información de voltaje configurada. El comando genera uno de estos bloques de datos para cada DIMM, separados por una sola línea en blanco cada uno.
Me gustaría poder obtener el bloque de información para una ranura DIMM específica según el Location Tag
campo, pero no estoy seguro de cómo hacerlo. Estoy bastante seguro de que esto se puede hacer, awk
pero solo sé cómo imprimir la coincidencia awk '/P1-DIMMD1/'
o la línea antes de la coincidencia.awk '/P1-DIMMD1/ {print a}{a=$0}'
¿Alguien sabe cómo podría extraer todo este bloque de datos si Location Tag
coincide con mi búsqueda ( P1-DIMMD1
)?
Respuesta1
Lo siguiente coincidirá con la etiqueta proporcionada en la variable de etiqueta:
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 }'
El guión AWK es
/ID SIZE TYPE/ {
block = $0
output = 0
next
}
{ block = block "\n" $0 }
/Location Tag/ { output = ($0 ~ tag) }
/Configured Voltage/ && output { print block }
Acumulamos un bloque en la block
variable y lo generamos cuando llegamos al final del bloque si vimos la etiqueta correcta en el proceso.
Respuesta2
Tú podríasutilizar ed...y¡Sed, hombre!
Tienes quedesearSin embargo, es mejor usar ed para este, ya que ed quiere operar en un archivo, no como parte de una canalización.
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
La ed
cadena de comandos se divide en cuatro \n
comandos separados:
- busque hacia adelante, usando
/
, para el texto "Etiqueta de ubicación: " seguido del valor de la$wanted
variable - busque hacia atrás, usando
?
, para el patrón: (inicio de línea), "ID", cualquier cosa, "TAMAÑO", cualquier cosa, "TIPO" - desde esa línea (
.
), hasta (,
) la siguiente línea que coincida con "Voltaje configurado", imprima esas líneas (p
) - dejar de fumar:
q
Debido a que ed imprime automáticamente la línea coincidente cuando buscas, solía sed
eliminar esas dos líneas aquí.
Respuesta3
Inspirándome en la gran respuesta de @Stephen Kitts, escribí un script un poco más general para realizar la coincidencia de bloques cuando tengo un patrón de inicio y fin específico.
#!/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 }
Uso:match_block START END MATCH [FILE]
./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1' f
o
command | ./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1'
Gracias por sugerir escribir esto awk
directamente como un guión. Mi script de shell original era:
#!/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"
Uso: match_block START END MATCH [FILE]
.
Si se omite el archivo, stdin
se utilizará.
En tu caso:
command | ./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1'
o
./match_block '^ID' 'Configured Voltage' 'Location Tag: P1-DIMMD1' file