【问题标题】:Deploy script needs to update an integer in a config file部署脚本需要更新配置文件中的整数
【发布时间】:2012-12-01 06:29:30
【问题描述】:

我正在编写一个 python 结构脚本,以简化我在不同环境中的解决方案部署。

到目前为止它工作得很好,但我在脚本末尾有一个提示,询问我是否要编辑 .yml 配置文件,基本上是为了更新我的资产版本。我在里面手动通过 vim 并基本上增加了这个数字:

  reconnection_delay: 50
  max_attempts: 500
  assets_version: 5360

我怎么可能只使用命令行自动执行此操作。似乎应该使用 sed 或 perl,但我对此并不熟悉,在这里可能会得到一些帮助!

谢谢

【问题讨论】:

    标签: perl unix command-line sed


    【解决方案1】:

    您可以使用 YAML tiny(或其他模块,例如:YAML::XS、YAML::Syck)来读取和写入 YAML 文件。

    https://metacpan.org/pod/YAML::Tiny

    use YAML::Tiny;
    use Data::Dumper;
    # Create a YAML file
    my $yaml = YAML::Tiny->new;
    #check what the content
    print Dumper($yaml);
    # Open the config
    $yaml = YAML::Tiny->read( 'file.yml' );
    # Changing data
    #$yaml->[0]->{section} = { this => 'that' };
    $yaml->[0]->{reconnection_delay} = 50;
    $yaml->[0]->{max_attempts} = 500;
    $yaml->[0]->{assets_version} = $yaml->{assets_version} + 1;
    
    # Save the file
    $yaml->write( 'file.yml' );
    

    【讨论】:

      【解决方案2】:
      perl -i.backup -pe 's{ ( \b assets_version: \s+ ) (\d+) $ }{ $1 . ( 1 + $2 ) }xmse;' your.yml
      

      这将创建一个名为 your.yml.backupyour.yml 副本,查找包含“assets_version:”的行并将数字加 1。

      【讨论】:

        【解决方案3】:

        sed 没有任何内置的算术方法,所以不容易做到。

        perl

        除了进行正确的 yaml 解析之外,您还可以使用这样的单行代码:

        perl -anE '$, = " "; $F[1]++ if $F[0] =~ /assets_version/; say @F'
        

        -a 开关将输入拆分为@F 数组,从而可以访问字段。

        sed

        GNU sed 可以调用外部程序,所以在 bc 的帮助下你可以这样做:

        /assets_version/ {
          h                                      # save line to hold space
          s/[^:]+:\s*(.*)/echo \1 + 1 | bc/e     # convert line to 'echo num + 1 | bc'
                                                 # and pass on to /bin/sh
          G                                      # append hold space to pattern space
          s/([^\n]+)\n([^:]+).*/\2: \1/          # reorder to replace with incremented
                                                 # number
        }'
        

        一行相同:

        sed -r '/assets_version/ { h; s/[^:]+:\s*(.*)/echo \1 + 1 | bc/e; G; s/([^\n]+)\n([^:]+).*/\2: \1/ }' 
        

        如果您想知道如何使用纯 sed 进行操作,以下是受 GNU sed 手册中的 cat -n 示例启发的一种方法(也适用于 BSD sed):

        inc.sed

        /assets_version/ { 
          h;                                                  # save for later
          s/[^:]+:\s*//;                                      # only keep number
          /^9*$/ s/^/0/;                                      # need one more number
          s/.9*$/_&/;                                         # mark what will change
                                                              # when incrementing
          H;                                                  # save for later
          s/^.*_//;                                           # only keep what will
                                                              # change
          y/0123456789/1234567890/;                           # transliterate numbers
          G;                                                  # append hold space
          s/([^\n]+)\n([^:]+:\s*)[^\n]+\n([^_]*).*/\2\3\1/;   # reorder to get result
        }
        

        注意,这只适用于非负整数。

        使用 GNU sed,像这样运行它:

        sed -r -f inc.sed infile
        

        BSD sed:

        sed -E -f inc.sed infile
        

        所有情况下的输出:

        reconnection_delay: 50
        max_attempts: 500
        assets_version: 5361
        

        【讨论】:

          【解决方案4】:
          awk '/assets_version/{$NF++}1' file > tmp && mv tmp file
          

          只查找 assets_version 并递增该行的最后一个字段。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-02-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-07
            • 1970-01-01
            相关资源
            最近更新 更多