通常、以前に回答した質問で回答を見つけますが、今回はそうではありません(または回答を理解できず、必要に応じて変更できません)。だから最初の質問になります。ここで。
私の入力ファイルは次のとおりです
# -*- 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
を処理します。