システム構成をawkまたはsedと比較しやすい形式に変換してみてください。

システム構成をawkまたはsedと比較しやすい形式に変換してみてください。
  1. exitサブセクションがセクションの終わりを表示または表示するupタブとして宣言されているこれらの設定スタイルの用語が何であるかを知っている人はいますか?

    config
        system
            security
                tacacs
                    server 1.1.1.1 port 88 
                    profile "default"
                exit
                user "one"
                    profile "admin" "reports"
                    password "E$OITGJ@vf2m92;l3j1"
                    home /home/one
                exit
            logs
                log 1
                    data foo
                    data bar
            exit
    
  2. 同じタブ行(この場合)でセクション終了宣言を見つけてタイトルを宣言するためにawk///sed何でも使用できる方法はありますか?次に、そのセクションの各行の前にタイトルを挿入すると、次のようになります。 (引用符は選択できます)?trexit

    config system security tacacs server "1.1.1.1" port "88"
    config system security tacacs profile "default"  
    config system security user "one" profile "admin" "reports"
    config system security user "one" password "E$OITGJ@vf2m92;l3j1"
    config system security user "one" home "/home/one" 
    config system logs log "1" data "foo"
    config system logs log "1" data "bar"
    

最大の問題は、セクション数と個々のセクションの名前が異なるボックス/OSバージョンの間で固定されていないため、ユーザーごとまたはセクションごとに異なる設定を持つ20人のユーザーまたは50個のログを持つことができることです。各セクションにはより多くのセクションがあります。他のデフォルト値または設定フラグ名を使用してください。

awkandsedのようなものを使ってこれを行うことができるはずですが、/(^.*$)(\t\b.*$)*,(exit)/\1\s\2/この方法では設定に1行だけ入力できます。

答え1

形式が思い出されるmtree構成形式(参照)ここ例えば)。

次のawkプログラムは、データを上記の新しい形式に再フォーマットします。各セクションは4つのスペースの倍数でインデントされていると仮定しますが、単一のタブを使用するようにFS変数を変更できる必要があります。" {4}""\t"

BEGIN { FS = " {4}" }

$NF == "exit" { next }

NF > nf {
        section[++nf] = $NF
        next
}

function output() {
        $0 = ""
        for (i = 1; i <= nf; ++i)
                $i = section[i]
        print
}

{
        hold = $NF
        hold_nf = NF

        output()

        nf = hold_nf
        section[nf] = hold
}

END { output() }

このnf変数は、現在のセクションのフィールド数、つまり構成行の「セグメント」数です。このsection配列は現在のnfフィールド数を保持します。

コードのブロックは次のとおりです。

  • BEGIN:このブロックは、FS入力フィールド区切り文字を正確に4つのスペースに一致する拡張正規表現で初期化します。

  • $NF == "exit":このブロックは「終了」とマークされた行をスキップします。これは不要であることがわかりました(1つのセクションは前のセクションより小さいインデントで終わります)。

  • NF > nf:このブロックは、nf現在の入力ラインの終わりから配列sectionの最後のフィールドまでデータを増分して追加します。nextこの入力ラインのさらなる処理をスキップするために、ブロックの最後でそれを呼び出します。

  • function output():呼び出し時に現在の区間を出力する関数です。次の2つのブロックでこれを呼び出します。

  • 無条件ブロック:ここに来たら、現在のセクションを出力する必要があります(現在のセクションが終了しているか、少なくとも分割されていません)。関数を呼び出してoutput()これを行います。それでもその入力行にデータをインポートして保存する必要があり、output()現在の入力レコードがリセット($0)されているので、保持したいデータをに保存しますhold。値NFより低い可能性がある値に対して同じことを行いますnf

  • END:入力が終了すると、最後の設定セクションがまだ出力されていません。これはを呼び出すことによって行われますoutput()

質問に提供されたデータをテストします。

$ awk -f script file
config system security tacacs server 1.1.1.1 port 88
config system security tacacs profile "default"
config system security user "one" profile "admin" "reports"
config system security user "one" password "E$OITGJ@vf2m92;l3j1"
config system security user "one" home /home/one
config system logs log 1 data foo
config system logs log 1 data bar

関連情報