3

私は、さまざまな環境でのソリューションの展開を容易にする Python ファブリック スクリプトに取り組んでいます。

これまでのところ問題なく動作していますが、スクリプトの最後に、.yml 構成ファイルを編集してアセットのバージョンを更新するかどうかを尋ねるプロンプトが表示されます。内部のvimを手動で調べ、基本的にその数を増やします:

  reconnection_delay: 50
  max_attempts: 500
  assets_version: 5360

コマンドラインだけで自動的にそれを行うにはどうすればよいでしょうか。sed または perl を使用する必要があるようですが、私はそれに慣れていません。ここでいくつかの助けをいただければ幸いです。

ありがとう

4

4 に答える 4

3

sed には算術演算を行う組み込みの方法がないため、簡単ではありません。

パール

適切な yaml 解析を行う以外に、次のようなワンライナーで問題を解決できます。

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

スイッチは-a入力を配列に分割@Fし、フィールドへのアクセスを提供します。

シード

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
}'

1行で同じ:

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

cat -n純粋な sed でそれを行う方法を知りたい場合は、GNU sed マニュアルの例に触発された 1 つの方法を次に示します (BSD 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 -E -f inc.sed infile

すべての場合の出力:

reconnection_delay: 50
max_attempts: 500
assets_version: 5361
于 2012-12-13T13:52:54.160 に答える
2
awk '/assets_version/{$NF++}1' file > tmp && mv tmp file

assets_version を探して、行の最後のフィールドをインクリメントします。

于 2012-12-13T14:46:42.700 に答える
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' );
于 2012-12-13T11:41:14.837 に答える