sed
次のように、長いファイル(Junos構成)から中括弧で区切られた構成チャンクを抽出しようとしています。
group foo {
command;
setting {
value;
}
command;
}
}
最初のインデント行と同じ場所で停止するのは秘密です。
sed
あるパターンから別のパターンにマッチングを使用する方法を学びました。、以下を試しました。
$ sed -rn '/^( *)group foo/,/^\1\}/p' config.txt
sed: -e expression #1, char 41: Invalid back reference
問題は、2つの別々のスキーマと逆参照が両方の間で機能しないこと/^( *)group foo/
です。/^\1\}/
では、どうすればこれを達成できますか?
ベストアンサー1
あなたは正しいです:それでも逆参照は基本正規表現で定義されています。(着替え)(各sedアドレスはBREなので、逆参照をサポートする)、逆参照は他のBREで定義されているキャプチャリンググループを取得できません。したがって、このアドレスのキャプチャグループは/^( *)group foo/
他のアドレスから取得できません/^\1\}/
。
これはtest.awk
、開かれたかっこと閉じたかっこを計算することによって行われます。
brk && /\{/{brk++} #Increment brk if brk is not zero and line contains {
brk && /\}/{brk--} #Decrement brk if brk is not zero and line contains }
/^[[:blank:]]*group foo \{/{brk=1;prt=1} #Set brk and prt if match initial pattern
prt #Print line if prt is set
!brk && prt{prt=0} #If brk is zero and prt is not, set prt=0
$ cat file
foo bar
foo bar2
}
group foo {
command;
setting {
value;
}
command;
}
dri {
}
end
$ awk -f test.awk file
group foo {
command;
setting {
value;
}
command;
}
別のあまりエレガントなオプションは、空のスペースを計算することです。これがまさに試みの背景になるアイデアです。インデントにタブがあると壊れます。
/^ *group foo \{/{
match($0,/^ */) #Sets RLENGTH to the length in characters of the matched string
i=RLENGTH
}
i #If i is set, the current line is printed
i&&/^ *\}$/{
match($0,/^ */) #Again, sets RLENGTH to the length of the matched string
if(RLENGTH==i){i=0} #If the value is equal to the one from group foo line, unset i
}