exit
或up
表示该部分的末尾:配置系统安全策略服务器1.1.1.1端口88配置文件“默认”“退出用户”、“管理”报告“密码"E$OITGJ@vf2m92;l3j1“home /home/一个出口日志日志1数据foo数据栏出口”awk
/sed
/tr
/whatever是否有一种方法通过查找位于同一制表行(本例中为exit
)的节尾声明来声明标头,然后在该小节的每一行前面插入标题,使其看起来更像(可选引号)?配置系统安全策略服务器"1.1.1.1“端口"88”配置系统安全策略配置文件配置系统安全用户“一个”配置系统安全用户“一个配置系统安全用户”报告“配置系统安全用户”一个密码E$OITGJ@vf2m92;l3j1“配置系统安全用户”“一个”配置系统安全用户“一个”配置系统日志"1“数据"foo”配置系统日志日志"1“数据"bar”主要问题是,在不同的框/OS版本之间,子部分的数量和不同片段的名称并不是静态的,因此我可能有20个用户或50个日志,每个设置都不同,每个小节还有更多具有不同默认值或配置标志名的子节。
看起来我应该可以用awk
和sed
来完成这个任务,比如/(^.*$)(\t\b.*$)*,(exit)/\1\s\2/
,但是这只会让我进入配置中的一行。
发布于 2021-03-04 20:40:10
这种格式让人想起了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
https://unix.stackexchange.com/questions/637549
复制相似问题