設定ファイルがあるとしましょう。
[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[extra]
[footer]
[tail]
print = true
[end]
[text]
以下のオプションがある場合にのみタイトル()を印刷したいと思います。したがって、出力は次のようになります。
[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[tail]
print = true
答え1
通常、読みやすくするために複数行で書いていますが、1行を要求したので、
perl -ne '$head = $_ and next if /^\[/; $head and print $head and undef $head; print'
答え2
ポータブルsed; gnu sedではないはずです。ファイルをconfのままにします。
sed -E 'N;/^\[.+\]\n\[.+\]$/!P;D' conf
Gnu sedがデフォルトのポータブルに設定されている場合
sed --posix -E 'N;/^\[.+\]\n\[.+\]$/!P;D' conf
答え3
$ awk '/^\[/ { head = $0; next } head != "" { print head; head = "" } { print }' file
[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[tail]
print = true
プログラムawk
は見つかった各ヘッダーを変数に保存しhead
、すぐに次の入力行に移動します。
行がいいえヘッダ行、head
変数に何かが含まれている場合はヘッダを出力します。その後、現在の行を出力します。
これはほとんど文字通りの翻訳です。Ed Greenの回答入力するawk
。
やや直接的には次のように変換されますsed
。ここでは、以下のように最新のヘッダーを維持するためにスペースが予約されています。
/^\[/ {
h; # store header in hold space (overwriting)
d; # delete pattern space, start next cycle
}
x; # swap with hold space
/./ { p; s///g; }; # if non-empty, print and empty
x; # swap with hold space
またはシングルライナーで
$ sed -e '/^\[/{ h;d; }' -e 'x; /./{ p;s///g; }' -e x file
[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[tail]
print = true
別の短いsed
バリエーションは、ファイルの末尾に空のセクション/ヘッダーがあるという事実に依存します。
$ sed -n -e'/^\[/{ x;/\n/p;d; }' -e H file
[main]
foo = bar
[option]
opt1 = opt2
opt3 = opt4
[tail]
print = true
これにより、ヘッダーとそれに関連する他の行が予約済みスペースに保存されます。新しいヘッダーが見つかると、予約済みスペースが置き換えられ、改行が確認されます。見つかったら印刷してください。他の行は単に予約済みスペースに追加されます。
なぜならawk
、これは次のとおりです
awk '/^\[/ { if (sect ~ ORS) print sect; sect = $0; next } { sect = sect ORS $0 }' file