我第一次尝试使用bash脚本,而且我仍然坚持使用sed
来修改配置文件。我需要编辑的键是非常通用的,并且在整个文件中使用,所以我必须依赖一个部分才能知道在哪里做什么"触摸"。
所以,如上所述,文件周围有多个部分,由[section name]
声明,然后在它下面,您有该部分的配置,由一个选项卡缩进。有enabled
,type
等密钥在整个文件中使用。
所以完整的部分看起来像这样:
[backend]
# enabled = no
# data source = average
# type = graphite
# destination = localhost
# prefix = netdata
# hostname = localhost
# update every = 10
# buffer on failures = 10
# timeout ms = 20000
所以我需要做的是:
enabled = no
更改为enabled = yes
destination
的值更改为包含端口(192.168.99.38:2003
)的IP地址hostname
的值更改为其他主机名,也就是机器的主机名($HOSTNAME
?)。事情是,我不确定如何解决这个问题。我一直在寻找sed多线处理,但我绝对不知道如何匹配[backend]
部分。这对我来说很新鲜。
答案 0 :(得分:1)
sed
不是这种东西的理想工具,但可以做到:
/^\[.*]$/h
{G;/\n\[backend\]$/{
s/#//
/enabled/s/no/yes/
/destination/s/localhost/whatever/
/hostname/s/localhost/something else/
}
s/\n\[.*\]$//
}
答案 1 :(得分:1)
当你评论我时:只有[后端]下的内容,没有别的
您可能会对 Perl 这样做感兴趣,如果不只是评论我;我会删除和回答。
说你有这个文件:
[no-backend]
# enabled = no
# data source = average
# type = graphite
# destination = localhost
# prefix = netdata
# hostname = localhost
# update every = 10
# buffer on failures = 10
# timeout ms = 20000
[backend]
# enabled = no
# data source = average
# type = graphite
# destination = localhost
# prefix = netdata
# hostname = localhost
# update every = 10
# buffer on failures = 10
# timeout ms = 20000
[no-backend]
# enabled = no
# data source = average
# type = graphite
# destination = localhost
# prefix = netdata
# hostname = localhost
# update every = 10
# buffer on failures = 10
# timeout ms = 20000
这个单行为您找到该部分:
perl -lne '$b=$.; $e=($b+10) if /\[backend\]/;print if $b++<$e' file
or readable version
perl -lne 'if( /\[backend\]/ ){ $b=$.; $e=( $b+10 ); }; if( $b++ < $e ){ print }' file
和输出:
[backend]
# enabled = no
# data source = average
# type = graphite
# destination = localhost
# prefix = netdata
# hostname = localhost
# update every = 10
# buffer on failures = 10
# timeout ms = 20000
现在代替打印,您可以使用以下内容修改该部分:
s/#//;s/no/yes/;s/(?<=destination = ).+$/192.168.99.38:2003/;s/(?<=hostname = ).+$/$HOSTNAME/
完整的单行
perl -lpe 'if(/\[backend\]/){$b=$.;$e=($b+10);};if($b++<$e){ s/#//;s/no/yes/;s/(?<=destination = ).+$/192.168.99.38:2003/;s/(?<=hostname = ).+$/\$HOSTNAME/ }' file
和输出:
[no-backend]
# enabled = no
# data source = average
# type = graphite
# destination = localhost
# prefix = netdata
# hostname = localhost
# update every = 10
# buffer on failures = 10
# timeout ms = 20000
[backend]
enabled = yes
data source = average
type = graphite
destination = 192.168.99.38:2003
prefix = netdata
hostname = $HOSTNAME
update every = 10
buffer on failures = 10
timeout ms = 20000
[no-backend]
# enabled = no
# data source = average
# type = graphite
# destination = localhost
# prefix = netdata
# hostname = localhost
# update every = 10
# buffer on failures = 10
# timeout ms = 20000
最后检查输出后是否一切正常,然后您可以使用-i
选项使用“就地编辑”功能,例如:
perl -i.bak -lne '...the rest of the script...' file
.bak仅用于备份旧文件。 (如:file.txt.bak)
更新 以发表评论
perl -lpe '$hn=qx(cat /etc/hostname);chomp $hn;if(/\[backend\]/){$b=$.;$e=($b+10);};if($b++<$e){s/#//;s/no/yes/;s/(?<=destination = ).+$/192.168.99.38:2003/;s/(?<=hostname = ).+$/$hn/ }' file
和输出:
...
...
[backend]
enabled = yes
data source = average
type = graphite
destination = 192.168.99.38:2003
prefix = netdata
hostname = k-five
update every = 10
buffer on failures = 10
timeout ms = 20000
...
...
答案 2 :(得分:1)
假设文本在configfile中,并且下面有另一个以“[”开头的部分,下面的解决方案应该可以使用
sed -i '/\[backend\]/,/\[/{s/#//;s/enabled = no/enabled = yes/;s/\(destination = \)\(.*\)\($\)/\1192\.168\.99\.38\:2003\3/;s/\(hostname = \)\(.*\)\($\)/\1'$HOSTNAME'\3/}' configfile
我们搜索[backend]和[之后的文本然后执行{}中包含的sed命令我们删除#然后编辑目标以及最后编辑主机名。
如果后端下面没有其他部分,请将命令更改为:
sed -i '/\[backend\]/,/^$/{s/#//;s/enabled = no/enabled = yes/;s/\(destination = \)\(.*\)\($\)/\1192\.168\.99\.38\:2003\3/;s/\(hostname = \)\(.*\)\($\)/\1'$HOSTNAME'\3/}' configfile