2014-02-20 77 views
0

我有以下的輸出,我想通過以下方式來格式化的Ruby腳本來:使用printf輸出格式?

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進行格式化?

+5

樂碼,請 –

回答

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")} 
+0

我修改了以下代碼在你的腳本中輸入= myrubyoutput format =「%-12s%14s \ n」 printf(format,「Name 「,」Build Date「) input.each {| x |放置x.gsub(/(。*?)\ s + Build-Date:\ s +(。*)/,「\\ 1 \ t \\ 2」)} ' – Satish

+0

簡而言之,您的邏輯適合我:) – Satish

+0

爲什麼拆分行而不是加載整個文件並使用我的正則表達式? – Abdo

3

我會做使用Ruby的STDLIBCSV

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 
+0

更靈活的方法:-) +1 – Abdo

+0

@Abdo是的,都是由Ruby做的。我只是安排他們滿足輸出。 Lolz :-) –

+1

哈哈..是的,但我的意思是,使用CSV爲此目的是可重複使用和靈活的。您可以輕鬆添加更多列並處理輸入更改:-) – Abdo

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}" 
} 
+0

你很好.. +1 ..我沒有太多成熟的理解這段代碼。 :-) –

+0

你的意思是正則表達式?我只是用http://rubular.com來弄清楚這個模式:-) – Abdo

+0

是的..正則表達式。我對此感到不舒服。仍然從互聯網上學習。 :( –

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 

,你應該小號ee是這樣的:

Name  Build-Date 
tomcat7.0 20140220-1147 
tomcat7.1 20140220-1147 
tomcat7.2 20140220-1147 
tomcat7.3 20140220-1147 

對後者的好處是你正在處理只做一件事的小型專業腳本。通過管道(「|」)組合它們是* nix建立小應用程序的大型應用程序的方式。

+0

你可以給我的文檔'|'管道的鏈接? –

+0

好的我得到了['使用管道字符'](http://ruby.about.com/od/tutorials/a/commandline_3.htm)它。 –