
У меня есть файл, который выглядит примерно так:
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
и , в противном случае выводитсяRLENGTH
NA
решение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>