文字列を含まないすべての行と隣接する行をどのように印刷しますか?

文字列を含まないすべての行と隣接する行をどのように印刷しますか?

私はその仕事に集中しようとしています。Auto-installed: 1次の出力に含まれるすべての行と前の2行を除外したいと思います。私は間違いなくこれがgrep -v -B2 string問題を解決すると思いました。言うまでもなく、状況はさらに悪化しました。

内容は次のとおりです。

Package: libopencore-amrwb0
Architecture: amd64
Auto-Installed: 1

Package: transfig
Architecture: amd64
Auto-Installed: 0

Package: xfig-libs
Architecture: amd64
Auto-Installed: 1

Package: xaw3dg
Architecture: amd64
Auto-Installed: 0

結果は次のとおりです。

Package: transfig
Architecture: amd64
Auto-Installed: 0

Package: xaw3dg
Architecture: amd64
Auto-Installed: 0

(空白行は表示されません。空白行が表示されない場合はプラスですが必須ではありません。結果には、サイレントインストール値が0のパッケージも含める必要があります。)

私もできることを知っています改行文字の一致しかし、何も印刷されないか、すべてが印刷されますが、間に改行があります。

どんな解決策でも許されます。 grep(Emacsでも)。

答え1

データがどのように構成されているかはよくわかりませんが、表示されているとしたら、次はどうですか?

grep -B2 'Auto-Installed: [^1]'

これは各セクションに1行が含まれていると仮定しますが、Auto-Installedこれは正確ではないかもしれません。

これはawkプログラムです。

awk 'BEGIN{deleted=3}
     !deleted{printf "%s",l[NR%3]}
     deleted {--deleted}
     {l[NR%3]=/./?$0"\n":$0}
     /Auto-Installed: 1/{deleted=3}
     END{for(i=NR+deleted;i<NR+3;++i)printf "%s",l[i%3]}'

答え2

私の考えでは、これはあなたに役立つと思います。

sed ':a
     $!N                          # slurp
     /Auto-Installed: 1/s/.*//    # kill all buffered on match
     $!{/\n.*\n/{P;D}}            # P/D any third line, D cycles w/o read
     $!ba                         # if no P/D, cycle w/o read anyway
    '

答え3

これらを除外しようとする代わりに、目的の反対行を選択するのはどうですか?

$ grep -B 2 "Auto-Installed: 0" data.txt 
Package: transfig
Architecture: amd64
Auto-Installed: 0

「Autoinstall:1」を含むセクションを除外

"autoinstall:1" を含むセクションを除外する問題を解決するために使用したいのですが、grepロジックを使用している場合、私はこの方法を考えていません。PCRE設備GNU grepから。

$ grep -B2 -P 'Auto-Installed: (?!1)' data.txt 

はい

$ grep -B2 -P 'Auto-Installed: (?!1)' data.txt 
Package: transfig
Architecture: amd64
Auto-Installed: 0

上で使用Perlの予測機能(?!..).これにより、後で一致する値の値1を含まない行を見つけることができますAuto-Installed:。次に、「一致」()の前に2行を表示するように指示しますgrep-B2

答え4

これは必須のPerl方式です:

perl -000ne 'print unless /Auto-Installed: 1/' file

奇跡的に、-000これはPerlの短絡モードこれにより、ファイルが段落に分割されます。つまり、レコードは 2 つ以上の連続した\n文字で区切られます。

また、項目間に空白行が印刷されます。これを削除するには実行できます。

perl -000ne 'print unless /Auto-Installed: 1/' file | grep .

関連情報