#!/usr/bin/env ruby require "optparse" DEFAULT_QUANTILES = [0.25, 0.50, 0.75, 0.90, 0.95, 0.99, 0.999] def quantile(values, p, presorted = false) return values.first if values.size == 1 values = values.sort unless presorted hh = (values.size - 1) * p + 1 h = hh.floor v = values[h - 1] e = hh - h if e then v + e * (values[h] - v) else v end end options = {} OptionParser.new do |opts| opts.banner = "Usage: #{File.basename __FILE__} [options]" opts.on "-p", "--percentiles percentiles", "percentiles" do |v| percentiles = v.split(",").map &:to_f options[:quantiles] = percentiles.map {|i| i / 100.0} end end.parse! stream = STDIN.read values = stream.split("\n").map &:to_f values.sort! quantiles = options.fetch :quantiles, DEFAULT_QUANTILES summary = {"min" => values.min} quantiles.each do |q| label = "#{q * 100}%" summary[label] = quantile(values, q, true) end summary["max"] = values.max puts summary.keys.map {|i| i.rjust 6}.join "\t" puts summary.values.map {|i| i.round(4).to_s.rjust 6}.join "\t"