使用printf的输出格式?

时间:2014-02-20 19:54:44

标签: ruby format output

我有以下输出来自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

如何使用printfputs对其进行格式化?

4 个答案:

答案 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方式。