gpt4 book ai didi

bash - 使用 sed 处理一段完整的文本

转载 作者:行者123 更新时间:2023-12-04 18:57:35 27 4
gpt4 key购买 nike

我是第一次尝试 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 = noenabled = yes
  • 更改destination的值到带有端口的 IP 地址 ( 192.168.99.38:2003 )
  • 更改hostname的值到另一个主机名,可能是机器的主机名($HOSTNAME?)。

  • 问题是,我根本不知道如何解决这个问题。我四处寻找 sed 多行处理,但我绝对不知道如何匹配 [backend]仅限部分。这对我来说很新鲜。

    最佳答案

    As you comment me: Only what's under [backend], nothing else



    您可能会对 这样做感兴趣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
    ...
    ...

    关于bash - 使用 sed 处理一段完整的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43493457/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com