我有以下输出来自Ruby脚本,我想用以下方式格式化:
tomcat7.0 Build-Date: 20140220-1147
tomcat7.1 Build-Date: 20140220-1147
tomcat7.2 Build-Date: 20140220-1147
tomcat7.3 Build-Date: 20140220-1147
我想用以下格式:
Name Build-Date
tomcat7.0 20140220-1147
tomcat7.1 20140220-1147
tomcat7.2 20140220-1147
tomcat7.3 20140220-1147
如何使用printf
或puts
对其进行格式化?
答案 0 :(得分:3)
我会使用Ruby的 stdlib CSV:
require 'csv'
str = <<_
tomcat7.0 Build-Date: 20140220-1147
tomcat7.1 Build-Date: 20140220-1147
tomcat7.2 Build-Date: 20140220-1147
tomcat7.3 Build-Date: 20140220-1147
_
ar = []
option = { :write_headers => true,
:headers => ['Name','Build-Date'],
:return_headers => true,
:col_sep => " "
}
CSV.parse(str,option) do |row|
next ar << row.headers.to_csv(:col_sep => " "*9) if row.header_row?
ar << row.values_at(0,2).to_csv(:col_sep => " "*3)
end
puts ar
# >> Name Build-Date
# >> tomcat7.0 20140220-1147
# >> tomcat7.1 20140220-1147
# >> tomcat7.2 20140220-1147
# >> tomcat7.3 20140220-1147
答案 1 :(得分:2)
这样的事情怎么样? (我知道我没有使用printf =))
str = %(tomcat7.0 Build-Date: 20140220-1147
tomcat7.1 Build-Date: 20140220-1147
tomcat7.2 Build-Date: 20140220-1147
tomcat7.3 Build-Date: 20140220-1147)
LEFT_JUST = 15
puts "%s%s" % ['Name'.ljust(LEFT_JUST), "Build-Date"]
str.scan(/\S+(?=.)/).reject.with_index { |e, i|
i % 3 == 1 }.each_slice(2) { |l,r| puts "#{l.ljust(LEFT_JUST)} #{r}" }
输出:
Name Build-Date
tomcat7.0 20140220-1147
tomcat7.1 20140220-1147
tomcat7.2 20140220-1147
tomcat7.3 20140220-1147
修改:更好的正则表达式和代码如下:
LEFT_JUST = 15
str.scan(/(?<first>\S+)\s(\S+)\s(?<third>\S+)\n*/).each { |l,r|
puts "#{l.ljust(LEFT_JUST)} #{r}"
}
答案 2 :(得分:1)
您也可以使用正则表达式替换。
input = [
'tomcat7.0 Build-Date: 20140220-1147',
'tomcat7.1 Build-Date: 20140220-1147',
'tomcat7.2 Build-Date: 20140220-1147',
'tomcat7.3 Build-Date: 20140220-1147'
]
input.each{ |x| puts x.gsub(/(.*?)\s+Build-Date:\s+(.*)/, "\\1\t\\2")}
答案 3 :(得分:0)
这是使用String.%
(格式):
FORMAT = "%-9s\t%s"
TEXT_FILE_CONTENT = [
'tomcat7.0 Build-Date: 20140220-1147',
'tomcat7.1 Build-Date: 20140220-1147',
'tomcat7.2 Build-Date: 20140220-1147',
'tomcat7.3 Build-Date: 20140220-1147',
]
puts FORMAT % %w[Name Build-Date]
puts TEXT_FILE_CONTENT.map{ |l| FORMAT % /^(\S+).+?(\S+)$/.match(l).captures }
哪个输出:
Name Build-Date
tomcat7.0 20140220-1147
tomcat7.1 20140220-1147
tomcat7.2 20140220-1147
tomcat7.3 20140220-1147
你可以这样做:
TEXT_FILE_CONTENT.each{ |l| puts FORMAT % /^(\S+).+?(\S+)$/.match(l).captures }
%
将期望一个数组,因为格式中有两个占位符。这是阵列的来源:
/^(\S+).+?(\S+)$/.match('tomcat7.3 Build-Date: 20140220-1147').captures
# => ["tomcat7.3", "20140220-1147"]
如果您想将其作为管道进行,请将其另存为“s1.rb”:
TEXT_FILE_CONTENT = [
'tomcat7.0 Build-Date: 20140220-1147',
'tomcat7.1 Build-Date: 20140220-1147',
'tomcat7.2 Build-Date: 20140220-1147',
'tomcat7.3 Build-Date: 20140220-1147',
]
puts TEXT_FILE_CONTENT
这就是“s2.rb”:
FORMAT = "%-9s\t%s"
puts FORMAT % %w[Name Build-Date]
ARGF.each{ |l| puts FORMAT % /^(\S+).+?(\S+)$/.match(l).captures }
然后将它们运行为:
ruby s1.rb | ruby s2.rb
你应该看到类似的东西:
Name Build-Date
tomcat7.0 20140220-1147
tomcat7.1 20140220-1147
tomcat7.2 20140220-1147
tomcat7.3 20140220-1147
后者的优点是你正在使用只做一件事的小型专业脚本。通过管道(“|
”)组合它们是构建大型应用程序的* nix方式。