我有兴趣从命令行查询 Ruby的最新稳定版本。我主要对"1.9.3p327" 形式的字符串感兴趣。
更新#1
澄清一下,目标是始终查询最新的稳定版本,无论是 1.9.3p327 还是 3.0.2p392。
我有兴趣从命令行查询 Ruby的最新稳定版本。我主要对"1.9.3p327" 形式的字符串感兴趣。
更新#1
澄清一下,目标是始终查询最新的稳定版本,无论是 1.9.3p327 还是 3.0.2p392。
就像是:
curl 'http://ftp.ruby-lang.org/pub/ruby/1.9/' | ruby ./extract-and-print-max-patchlevel.rb
脚本的实现extract-and-print-max-patchlevel.rb
是读者的练习,但这是一个开始:
#!/usr/bin/env ruby
maxpatch=0
maxstr=nil
STDIN.each_line do |line|
next unless line =~ /1\.9\.3-p(\d+)\b/
patch = $1.to_i
if patch > maxpatch
maxpatch = patch
maxstr = $&
end
end
puts maxstr
请注意,它假定 Ruby 1.9.3 是最新的,因此您可能需要重新访问它。
Came back to this after starting to use rbenv. If you have rbenv installed, the following one-liner does the trick:
#!/usr/bin/env ruby
puts `~/.rbenv/bin/rbenv install --list`.split("\n").map{|item| item.strip}.select{|item| item[/^\d*\.\d*\.\d*/]}.reject{|item| (item.include? '-') && !(item =~ /-p\d*$/)}.last
你可以玩sed
或awk
。例如:
curl "http://ftp.ruby-lang.org/pub/ruby/1.9/" | sed -E 's/^.*"(ruby-)(1.9.3-p[0-9]+)(.*)".*$/\2/' | sed -e '/^1.*/!d' | sort | sed '$!d'
我不是sed
专家,这里可能是更好的解决方案,但这条线有效。
在 @maerics' 和 @YevgeniyAnfilofyev 的答案之间进行选择,我发现 Ruby 更真实,并将其变成单行,假设 curl 中的列表已经排序,所以我们只需要最后一行满足条件:
curl 'http://ftp.ruby-lang.org/pub/ruby/1.9/' 2> /dev/null | ruby -e "puts STDIN.lines.map { |x| /1\.9\.3-p\d+\b/.match(x) }.compact.last[0]"
或者,Ruby 部分扩展:
puts STDIN.lines.map do |x|
/1\.9\.3-p\d+\b/.match(x) # After such map we will get an array of MatchData or nils
end.compact.last[0] # Then we remove nils using Array#compact,
# get last MatchData and retrieve matched string with [0]
遵循一个良好的传统,给这个脚本添加排序作为练习留给读者:)
UPD: Of course, hard-coded 1.9.3 is bad, but if we replace each digit 1, 9 and 3 with \d
, the regex seems to become more or less independent. The other problem is that we only look into .../ruby/1.9
folder of that ftp. This may be fixed if we, instead, look into .../ruby
folder first, and find all version-numbered folders with regex /\d\.\d\//
. Then repeat the above query, joining results from all folders. But, of course, this already cannot made into a one-liner...