
Tengo un archivo que se parece a este:
Volume1
created=Monday
blah blah
foo foo
lock mode=exclusive
ops
layer id=1
Volume2
created=Tuesday
jibber jabber
foo foo
ops
layer id=2
Volume3
created=Wednesday
blaaah
foooo
lock mode=shared
ops
layer id=3
Lo que me gustaría hacer es grep en "modo de bloqueo" y, si está ahí, imprimir esa línea completa; de lo contrario, me gustaría imprimir "NA". Parece que no puedo entender cómo imprimir algo para líneas que no coinciden. Estoy seguro de que awk o sed también podrían hacer esto.
He estado probando un código similar a:
grep -A6 Volume | grep "lock mode" <file>
Me gustaría que el resultado mostrara lo siguiente, para este ejemplo:
lock mode=exclusive
NA
lock mode=shared
Respuesta1
Es fácil con perl
:
perl -l -00 -ne 'print /lock mode.*/ ? $& : "NA"'
-l
establece el delimitador del campo de salida en nueva línea-00
: modo párrafo (los registros son párrafos)-ne code
: ejecuta código para cada registro de entrada- si el registro contiene
lock mode
seguidos de cualquier número de caracteres que no sean de nueva línea, imprima lo que coincida ($&
) oNA
de otra manera.
Básicamente lo mismo queLa solución awk de @iruvar, pero en perl
.
Respuesta2
Con awk
en modo párrafo
awk -v RS= '{match($0, /lock mode=[^\n]+/);
print RSTART? substr($0, RSTART, RLENGTH): "NA"}' file
Esto RS=
hace que cada párrafo se trate como un solo registro. el llamado afósfororellena las coordenadas de lock mode=....
en variables predefinidas RSTART
y RLENGTH
. Si RSTART
es distinto de cero, se imprime la subcadena correspondiente a RSTART
y ; de lo contrario, se imprimeRLENGTH
NA
Respuesta3
Con GNUsed
sed -n '
/Volume/!d
:a
n
/lock mode/{
p
d
}
/^\s*$/!ba
c\NA
' <file>
Conawk
awk '
BEGIN{
FS="\n"
RS="\n\n"
}
/lock mode/{
for(i=1;i<=NF;i++)
if($i ~ /lock mode/)
print $i
next
}
{
print "NA"
}
' <file>