1

我不是 Ruby 开发人员,但我正在尝试使用 1 行 Ruby 脚本来增加我们使用 Jenkins 构建的 Grails 应用程序的 3 部分版本号。版本号存储在一个名为 application.properties 的简单属性文件中。我知道有很多方法可以做到这一点,但我的问题是针对 Ruby 以及为什么它不起作用。

为了测试,我将 application.properties 减少到一行:

app.version=0.2.8

我想做的就是增加最后一个数字。而已。因此,我在网上找到了一些代码并对其进行了破解:

ruby -pi.bak -e 'sub(/^app\.version=(\d+)\.(\d+)\.(-?\d+)/) { "app.version=#{$1}.#{$2}.#{$3.to_i.next}" }' application.properties

此代码在 OS X 上的 Ruby 1.8.7 上完美运行,但在 Linux 上的 Ruby 1.9.3 上失败:

-e:1:in `sub': wrong number of arguments (1 for 1..2) (ArgumentError)
    from -e:1:in `sub'
    from -e:1:in `<main>'

请注意,如果直接应用于字符串文字,则该表达式在 Linux 上有效:

ruby -e 'puts "app.version=0.2.8".sub(/^app\.version=(\d+)\.(\d+)\.(-?\d+)/) { "app.version=#{$1}.#{$2}.#{$3.to_i.next}" }'

我也尝试过 gsub 但这也不起作用(但出于不同的原因)。

我必须在这里遗漏一些简单的东西。我已经尝试过使用带有 sub() 的闭包的其他示例,它似乎工作正常。

4

2 回答 2

1

由于 BernardK 建议并非所有版本的 Ruby 都将 -p 视为相同,并且由于我的代码在应用于字符串文字时有效,因此这里有一个适用于 1.8.7 和 1.9.3 的解决方案。创建一个名为 incAppVersion.rb 的文件:

if $_ =~ /^\s*app\.version\s*=/
    print $_.sub(/(\d+)\.(\d+)\.(-?\d+)/) { "#{$1}.#{$2}.#{$3.to_i.next}" }
else
    print $_
end

并运行它:

ruby -ni.bak incAppVer.rb application.properties 

-n 很酷!

请随时提出改进建议。

于 2012-12-30T12:31:40.277 回答
0
$ ruby -pi.bak -e'$_.chomp!; $_ = $_[0..-2] + $_[-1, 1].succ + "\n" if $_[0..11] == "app.version="' application.properties

正如 Pickaxe(*) 对 -p 的解释:将您的程序代码放在循环 while gets; ...; print; end中。

gets将刚刚读入的行放入$_.
chomp!删除 CRLF。
print没有参数 prints $_,因此我们必须修改 $_ :$_ = ...
$_[0..-2]是输入行,除了最后一个字符
$_[-1, 1]是最后一个字符,长度为 1(在 Ruby 1.8 中需要获取一个字符,而不是数字)
$_[-1, 1].succ是下一个
+ "\n"要放置的字符/数字再次 CRLF(在 Windows 上将其更改为“\r\n”)
if $_[0..11] == "app.version="以仅处理所需的属性

$ ruby -v
ruby 1.9.2p320 (2012-04-20 revision 35421) [x86_64-darwin12.2.0]

在 OS X ML 上测试。
之前的文件:

app.version=0.2.8
line2

两次执行后的文件:

app.version=0.2.10
line2

(*) http://pragprog.com/book/ruby3/programming-ruby-1-9

于 2012-12-28T23:05:49.050 回答