使用带闭包的子方法的Ruby错误

时间:2012-12-28 20:20:42

标签: ruby regex

我不是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()的闭包的其他示例,它似乎工作正常。

2 个答案:

答案 0 :(得分: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很酷!

请随时提出改进建议。

答案 1 :(得分: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打印$_,因此我们必须修改$ _:$_ = ...
$_[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