本文共 11741 字,大约阅读时间需要 39 分钟。
github 链接: 。我们都知道 MySQL 的输出一般像下边这样的(格式化输出打印,很好看):
mysql> select * from tb_person;+----+----------+-------------+------+------+-------------+---------------------+| id | name | phone | age | sex | description | create_time |+----+----------+-------------+------+------+-------------+---------------------+| 1 | zhangsan | 132****2889 | 25 | M | NoDesc | 2020-11-30 20:03:07 || 3 | lisi | 152****7873 | 18 | F | None | 2020-11-30 20:08:33 || 5 | wangwu | 136****2908 | 25 | M | Nothing | 2020-11-30 20:10:11 || 10 | zhaoliu | 138****5322 | 15 | M | Nothing | 2020-11-30 20:12:11 |+----+----------+-------------+------+------+-------------+---------------------+
而且 Python 也有类似的第三方库来打印这种表格,比如 来构造类似的输出(用的 prettytable)。 那么 Ruby 怎么像这样格式化打印结果呢?
gem install terminal-table
[root@master ~]# gem install terminal-tableFetching terminal-table-2.0.0.gemFetching unicode-display_width-1.7.0.gemSuccessfully installed unicode-display_width-1.7.0Successfully installed terminal-table-2.0.0Parsing documentation for unicode-display_width-1.7.0Installing ri documentation for unicode-display_width-1.7.0Parsing documentation for terminal-table-2.0.0Installing ri documentation for terminal-table-2.0.0Done installing documentation for unicode-display_width, terminal-table after 0 seconds2 gems installed
require 'terminal-table'
require 'terminal-table'tb = Terminal::Table.newtb.title = "Terminal Table Testing"tb.headings = ["id", "name", "phone", "age", "sex", "description", "create_time"]tb.add_row([1, "zhangsan", "132****2889", 25, "M", "NoDesc", "2020-11-30 20:03:07"])tb.add_row([3, "lisi", "152****7873", 18, "F", "None", "2020-11-30 20:08:33"])tb.add_row([5, "wangwu", "136****2908", 25, "M", "Nothing","2020-11-30 20:10:11"])tb.add_row([10,"zhaoliu", "138****5322", 15, "M", "Nothing","2020-11-30 20:12:11"])tb.align_column(0, :right)puts tb
+----+----------+-------------+-----+-----+-------------+---------------------+| Terminal Table Testing |+----+----------+-------------+-----+-----+-------------+---------------------+| id | name | phone | age | sex | description | create_time |+----+----------+-------------+-----+-----+-------------+---------------------+| 1 | zhangsan | 132****2889 | 25 | M | NoDesc | 2020-11-30 20:03:07 || 3 | lisi | 152****7873 | 18 | F | None | 2020-11-30 20:08:33 || 5 | wangwu | 136****2908 | 25 | M | Nothing | 2020-11-30 20:10:11 || 10 | zhaoliu | 138****5322 | 15 | M | Nothing | 2020-11-30 20:12:11 |+----+----------+-------------+-----+-----+-------------+---------------------+
给大家来个实际的例子压压惊。(@tb.align_column 对齐一般在数据添加完成后再设置,如果先设置的话,是不会生效的哟!)
# test.json{ "title": "Hackbench Performance Testing", "unit": "KB/s", "x_name": "bs|test_size", "tables": { "fio.read_iops": { "average": { "dimensions": [ "compare_dimension", "openeuler 20.03" ], "source": [ [ "4k|1G", "4k|80G", "16k|1G", "32k|1G", "64k|1G", "128k|1G", "256k|1G", "512k|1G", "1024k|1G" ], [ "openeuler 20.03", 144076.2903315, 11601.099817, 37865.30472368628, 21145.10375497826, 14010.34254665909, 6701.240849466667, 3205.077255, 1367.476930860465, 673.3270888666667 ] ] }, "standard_deviation": { "dimensions": [ "compare_dimension", "openeuler 20.03" ], "source": [ [ "4k|1G", "4k|80G", "16k|1G", "32k|1G", "64k|1G", "128k|1G", "256k|1G", "512k|1G", "1024k|1G" ], [ "openeuler 20.03", 195, 0, 214, 205, 188, 183, 180, 191, 191 ] ] } }, "fio.write_iops": { "average": { "dimensions": [ "compare_dimension", "centos 7.6", "openeuler 20.03" ], "source": [ [ "4k|1G", "16k|1G", "32k|1G", "64k|1G", "128k|1G", "256k|1G", "512k|1G", "1024k|1G" ], [ "centos 7.6", 345243.028251, 142698.794456, 62108.34762725, 34747.729395, 26330.187008999997, 10317.85034025, 7471.708886999999, 3558.2993653999997 ], [ "openeuler 20.03", 122003.54468561111, 33528.52637123529, 31469.058358695653, 13870.135498022726, 8249.707439577778, 4329.454872088889, 1976.5380473953487, 1141.003158088889 ] ] }, "standard_deviation": { "dimensions": [ "compare_dimension", "centos 7.6", "openeuler 20.03" ], "source": [ [ "4k|1G", "16k|1G", "32k|1G", "64k|1G", "128k|1G", "256k|1G", "512k|1G", "1024k|1G" ], [ "centos 7.6", 97, 95, 122, 125, 100, 130, 101, 103 ], [ "openeuler 20.03", 174, 188, 171, 197, 181, 175, 170, 176 ] ] }, "change": { "dimensions": [ "compare_dimension", "centos 7.6 vs openeuler 20.03" ], "source": [ [ "4k|1G", "16k|1G", "32k|1G", "64k|1G", "128k|1G", "256k|1G", "512k|1G", "1024k|1G" ], [ "centos 7.6 vs openeuler 20.03", 183.0, 325.6, 97.4, 150.5, 219.2, 138.3, 278.0, 211.9 ] ] } } }}
# test.rbrequire 'json'require 'terminal-table'# ----------------------------------------------------------------------------------------------------# format compare template results into a table format#class FormatTableData def initialize(result_hash, row_size=8) @title = result_hash['title'] @tables = result_hash['tables'] @unit = result_hash['unit'] @x_name = result_hash['x_name'] @row_size = row_size end def show_table @tables.each do |table_title, table| @tb = Terminal::Table.new set_table_title row_num = get_row_num(table) split_data_column(table_title, table, row_num) set_align_column print_table end end def set_table_title @tb.title = "#{@title} (unit: #{@unit}, x_name: #{@x_name})" end def get_row_num(table) data_column_size = table['average']['source'][0].size row_num = data_column_size / @row_size row_rem = data_column_size % @row_size if row_rem > 0 row_num += 1 end row_num end def split_data_column(table_title, table, row_num) row_num.times do |row| starts = 1 + row * @row_size ends = starts + @row_size set_field_names(table_title, table, starts, ends) add_rows(table, starts, ends) break if row == row_num - 1 @tb.add_separator @tb.add_separator end end def set_field_names(table_title, table, starts, ends) field_names = [table_title] field_names.concat(table['average']['source'][0][starts-1...ends-1]) @tb.add_row(field_names) @tb.add_separator end def add_rows(table, starts, ends) row_names = %w[average standard_deviation change] max_size = row_names.map(&:size).max row_names.each do |row_name| next unless table[row_name] dimensions_size = table[row_name]['dimensions'].size (1...dimensions_size).each do |index| add_row(table, row_name, index, max_size, starts, ends) end end end def add_row(table, row_name, index, max_size, starts, ends) row = table[row_name]['source'][index] row_title = [row_name + ' ' * (max_size - row_name.size), row[0]].join(' ') format_data_row = row[starts...ends] if row_name == 'change' format_data_row.map! { |data| format('%.1f%%', data) } else format_data_row.map! { |data| format('%.2f', data) } end @tb.add_row([row_title, *format_data_row]) end def set_align_column @tb.number_of_columns.times do |index| @tb.align_column(index + 1, :right) end @tb.align_column(0, :left) end def print_table puts @tb puts endendresult_hash = JSON.load(File.open('test.json'))table_results = FormatTableData.new(result_hash, 9)table_results.show_table
+------------------------------------+-----------+----------+----------+----------+----------+---------+---------+---------+----------+| Hackbench Performance Testing (unit: KB/s, x_name: bs|test_size) |+------------------------------------+-----------+----------+----------+----------+----------+---------+---------+---------+----------+| fio.read_iops | 4k|1G | 4k|80G | 16k|1G | 32k|1G | 64k|1G | 128k|1G | 256k|1G | 512k|1G | 1024k|1G |+------------------------------------+-----------+----------+----------+----------+----------+---------+---------+---------+----------+| average openeuler 20.03 | 144076.29 | 11601.10 | 37865.30 | 21145.10 | 14010.34 | 6701.24 | 3205.08 | 1367.48 | 673.33 || standard_deviation openeuler 20.03 | 195.00 | 0.00 | 214.00 | 205.00 | 188.00 | 183.00 | 180.00 | 191.00 | 191.00 |+------------------------------------+-----------+----------+----------+----------+----------+---------+---------+---------+----------++--------------------------------------------------+-----------+-----------+----------+----------+----------+----------+---------+----------+| Hackbench Performance Testing (unit: KB/s, x_name: bs|test_size) |+--------------------------------------------------+-----------+-----------+----------+----------+----------+----------+---------+----------+| fio.write_iops | 4k|1G | 16k|1G | 32k|1G | 64k|1G | 128k|1G | 256k|1G | 512k|1G | 1024k|1G |+--------------------------------------------------+-----------+-----------+----------+----------+----------+----------+---------+----------+| average centos 7.6 | 345243.03 | 142698.79 | 62108.35 | 34747.73 | 26330.19 | 10317.85 | 7471.71 | 3558.30 || average openeuler 20.03 | 122003.54 | 33528.53 | 31469.06 | 13870.14 | 8249.71 | 4329.45 | 1976.54 | 1141.00 || standard_deviation centos 7.6 | 97.00 | 95.00 | 122.00 | 125.00 | 100.00 | 130.00 | 101.00 | 103.00 || standard_deviation openeuler 20.03 | 174.00 | 188.00 | 171.00 | 197.00 | 181.00 | 175.00 | 170.00 | 176.00 || change centos 7.6 vs openeuler 20.03 | 183.0% | 325.6% | 97.4% | 150.5% | 219.2% | 138.3% | 278.0% | 211.9% |+--------------------------------------------------+-----------+-----------+----------+----------+----------+----------+---------+----------+
转载地址:http://tnjqi.baihongyu.com/