Я пытаюсь напечатать строки, в которых есть совпадающая строка, но также хотел бы напечатать «NA» для других строк

Я пытаюсь напечатать строки, в которых есть совпадающая строка, но также хотел бы напечатать «NA» для других строк

У меня есть файл, который выглядит примерно так:

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

Я бы хотел сделать grep на "lock mode" и если он там есть, вывести всю строку, в противном случае я бы хотел вывести "NA". Я не могу понять, как вывести что-то для несовпадающих строк. Я уверен, что awk или sed тоже могут это сделать.

Я пробовал код, похожий на:

grep -A6 Volume | grep "lock mode" <file>

Для этого примера я хотел бы, чтобы вывод показывал следующее:

lock mode=exclusive  
NA  
lock mode=shared

решение1

Это легко с perl:

perl -l -00 -ne 'print /lock mode.*/ ? $& : "NA"'
  • -lустанавливает разделитель выходного поля на новую строку
  • -00: режим абзаца (записи — это абзацы)
  • -ne code: выполнить код для каждой входной записи
  • если запись содержит lock modeза которыми следует любое количество символов, не являющихся символами новой строки, то вывести то, что совпало ( $&), или NAв противном случае.

В основном то же самое, что иawk-решение @iruvar, но в perl.

решение2

В awkрежиме абзаца

awk -v RS= '{match($0, /lock mode=[^\n]+/); 
  print RSTART? substr($0, RSTART, RLENGTH): "NA"}' file

Приводит RS=к тому, что каждый абзац рассматривается как отдельная запись. Вызовсоответствоватьзаполняет координаты lock mode=....в предопределенные переменные RSTARTи RLENGTH. Если RSTARTне равно нулю, выводится подстрока, соответствующая RSTARTи , в противном случае выводитсяRLENGTHNA

решение3

С GNUсед

sed -n '
    /Volume/!d
    :a
    n
    /lock mode/{
        p
        d
        }
    /^\s*$/!ba
    c\NA
    ' <file>

Сawk

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>

Связанный контент