我有一个文件,其中包含几个条目,如下所示:
Banana1015 {
versionName "1.0.2"
versionCode 4
}
BeachRadio {
versionName "1.0.0"
versionCode 1
}
BIGFROG104 {
versionName "1.0.3"
versionCode 4
}
我想创建一个perl脚本,我可以在其中传递要在此文件中搜索的条目的参数(即"BeachRadio"),然后它将仅针对该条目递增版本名称和版本代码,并保存文件。它可以只增加 versionName 中的第 3 位小数作为默认值,但理想情况下可以传递一个允许主要、次要或补丁版本增量的参数。
到目前为止,我所拥有的只是读取文件,并在找到"BeachRadio"条目时输出:
#!perl -w
$file="build.gradle";
open my $fh, "<", $file or die $!;
while (<$fh>) {
print if /BeachRadio/ .. /}/;
}
我感谢对此的任何帮助。
鉴于文件格式,一种方法是按段落阅读。然后将每个段落读入一个字符串,您可以在其上使用直接正则表达式。要阅读段落,我们设置输入记录分隔符($/)。
剩余位是仅更改已提交的参数的值
use warnings;
use strict;
use Getopt::Long;
my $file = 'build.gradle';
my $section = 'BeachRadio'; # default to test
my ($major, $minor, $patch);
GetOptions(
'file=s' => $file, 'section=s' => $section,
'major=i' => $major, 'minor=i' => $minor, 'patch=i' => $patch,
) or die "Usage: $0 ...";
{ # limit scope of $/ change if there is other code
local $/ = "nn";
open my $fh, '<', $file or die "Can't open $file: $!";
while (<$fh>)
{
if (/^s*$sections*{/)
{
s{versionNames*"K(d+).(d+).(d+)}
{join '.', $major//$1, $minor//$2, $patch//($3+1)}e; #"
s/versionCodes*K(d+)/$1+1/e;
}
print; # or write to file
}
}
我在正则表达式中使用{}{}
分隔符,以便可以在内部使用//
而不会转义。
K
是一种特殊形式的正面回视(?<=pattern)
,它丢弃了所有以前的比赛。所以我们不必把它全部放回替换件中,只需K
后匹配的部分。
由于/e
修饰符,替换端被评估为代码。替换字符串是通过每个数字的.
替换(其规定值(如果已定义)或现有值)连接而成的。 这使用定义或//
运算符。 最后一个数字至少递增 1,即默认值。
请注意,对于错误的文件/行格式,没有错误处理。请酌情添加检查。
这将在我的测试中的所有调用中打印预期输出。
你可以尝试这样的事情:
use feature qw(say);
use strict;
use warnings;
my $fn = 'build.gradle';
my $arg = shift;
open ( my $fh, '<', $fn ) or die "Could not open file '$fn': $!";
my $str = do { local $/; <$fh> };
close $fh;
if ( $str =~ /^s*Q$argEs*{/mg ) {
if ( $str =~ /s*versionNames*"d+.d+./sg ) {
my $save_pos = $+[0];
$str =~ s/G(d+)/$1+1/e;
pos( $str ) = $save_pos;
$str =~ s/Gd+"s*versionCodes*K(d+)/$1+1/se;
}
print $str;
}