Estoy intentando imprimir líneas que tienen una cadena coincidente pero también me gustaría imprimir "NA" para las otras líneas.

Estoy intentando imprimir líneas que tienen una cadena coincidente pero también me gustaría imprimir "NA" para las otras líneas.

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"'
  • -lestablece 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 modeseguidos de cualquier número de caracteres que no sean de nueva línea, imprima lo que coincida ( $&) o NAde otra manera.

Básicamente lo mismo queLa solución awk de @iruvar, pero en perl.

Respuesta2

Con awken 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 RSTARTy RLENGTH. Si RSTARTes distinto de cero, se imprime la subcadena correspondiente a RSTARTy ; de lo contrario, se imprimeRLENGTHNA

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>

información relacionada