尝试将系统配置转换为更易于与 awk 或 sed 进行比较的格式

尝试将系统配置转换为更易于与 awk 或 sed 进行比较的格式
  1. 有谁知道这种配置风格的术语是什么,其中子部分由带有exitup指示该部分结尾的选项卡声明:

    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/ trwhatever 通过查找同一选项卡行上的节结束声明(exit在本例中)来声明标题,然后将标题插入该小节的每一行前面,以便它看起来更像这样(引号可选)?

    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"
    

主要问题是小节的数量和各个部分的名称在不同的盒子/操作系统版本之间不是静态的,所以我可能有 20 个用户或 50 个日志,每个用户或每个小节都有不同的设置,每个小节还有更多具有不同默认值的小节或配置标志名称。

看起来我应该能够使用awksed之类的东西来做到这一点/(^.*$)(\t\b.*$)*,(exit)/\1\s\2/,但这只能让我在配置中输入一行。

答案1

该格式让人想起mtree配置格式(参见这里举个例子)。

以下awk程序将数据重新格式化为您提到的新格式。它假设每个部分缩进四个空格的倍数,但您应该能够将变量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输入字段分隔符初始化为恰好匹配四个空格的扩展正则表达式。

  • $NF == "exit":此块会跳过仅显示“退出”的行。事实证明我们不需要这些(一个部分以比前一个更小的缩进结束)。

  • NF > nf:此块递增nf并将当前输入行末尾的数据添加到section数组的最后一个字段。我们next在块的末尾调用以跳过对此输入行的进一步处理。

  • function output():这是一个当我们调用它时输出当前节的函数。我们从以下两个块中调用它。

  • 无条件块:如果我们到达这里,则必须输出当前部分(当前部分已经结束,或者至少没有进一步细分)。我们通过调用我们的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

相关内容