一致する文字列を含む行を印刷しようとしていますが、他の行にも「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です。パターンがあれば行全体を印刷し、そうでない場合は「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その他の項目を印刷します。

基本的に@iruvarのawkソリューション、しかしperl

答え2

短絡awkモード

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

これRS=により、各段落が単一のレコードとして扱われます。呼ぶマッチlock mode=....事前定義された変数RSTARTsumに座標を入力しますRLENGTH。 0以外の場合はRSTART合計RSTARTとその部分文字列を印刷し、それ以外の場合は印刷します。RLENGTHNA

答え3

GNUと共にsed

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

そしてアッ

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>

関連情報