ファイルから複数行を削除

ファイルから複数行を削除

通常、以前に回答した質問で回答を見つけますが、今回はそうではありません(または回答を理解できず、必要に応じて変更できません)。だから最初の質問になります。ここで。

私の入力ファイルは次のとおりです

# -*- coding: utf-8 -*-

[attachment]

[browser]


[changeset]

[components]
tracopt.versioncontrol.svn.svn_fs.subversionconnector = enabled
tracopt.versioncontrol.svn.svn_prop.subversionmergepropertydiffrenderer = enabled 
tracopt.versioncontrol.svn.svn_prop.subversionmergepropertyrenderer = enabled
tracopt.versioncontrol.svn.svn_prop.subversionpropertyrenderer = enabled

[header_logo]

[inherit]
file = /etc/trac/trac.ini

[logging]

添付ファイル、ブラウザ、チェンジセット、header_logo、ロギングなどの空のセクションをすべて削除したいです。空でない部分だけを残しておきます。出力ファイルは次のとおりです。

# -*- coding: utf-8 -*-

[components]
tracopt.versioncontrol.svn.svn_fs.subversionconnector = enabled
tracopt.versioncontrol.svn.svn_prop.subversionmergepropertydiffrenderer = enabled
tracopt.versioncontrol.svn.svn_prop.subversionmergepropertyrenderer = enabled
tracopt.versioncontrol.svn.svn_prop.subversionpropertyrenderer = enabled

[inherit]
file = /etc/trac/trac.ini

これはbashスクリプトで発生する必要があります。 sed:find regexの使用について考えましたが、\[.+\]\n(\n)+(?=\[)正規表現が何行になるかを事前に知っていて、それに応じてN使用する必要があるため、sedでは機能しないようです。正規表現はFinalではなくEOFでも機能するはず\[ですが\[

どうすればいいのかご存知ですか? sedより良い方法はありますか?

答え1

少し混乱していますsedが、可能です。

sed -n '
:start
/^\[/{
    h
  :loop
    n
    /^\[/b start
    /^$/b loop
    x;p;g
}
p'

-nデフォルトでは何も印刷されないことを示します。:start後でgotoのためのラベル。行の先頭を一致させ、[一連の({...})コマンドを実行します。行を予約済みスペース(h)にコピーします。次の行(n)を取得します。起動すると[空のセクションがあるので、(b)に進み、再起動してください。

行が空の場合(/^$/)、別の行を読み込みます(gotoループ)。行は空ではないため、保持されているセクションヘッダー(x)に行を置き換え、セクションヘッダー(p)を印刷し、現在の行(g)を取得し、コマンドグループから行を印刷し続けます(p)。最後の(p)もセクションではなくヘッダを印刷します。

答え2

次のawkで来ました

BEGIN { empty=0 ; section = "" ; }
substr($0,1,1) == "[" { section = $0 ; next ; }
NF == 0 { if ( empty++ ) print ; section = "" ; next ; }
NF > 0  { if ( section != "" ) print section ; print ; section = "" ; }

として呼び出されます

awk -f pgm.awk infile > outfile

しかし、Terdonが述べたように、ライブラリを使用する方が良いです。このファイル形式はそれほど秘密ではなく、ライブラリは、crおよび cr/nl行末nlを処理します。

関連情報