diff --git a/README b/README index de9d5d4..5b4af98 100644 --- a/README +++ b/README @@ -12,6 +12,16 @@ and set in ~/.bashrc: export HISTCONTROL="ignoreboth" +== USAGE +See the --help also, + Usage: bash_history [options] + --inspect inspect the data + -l, --list list history + --fix fix times + -f, --find PAT find a command with pattern PAT + + + == LICENSE Copyright (c) 2012 Vincent Batts, Raleigh, NC, USA diff --git a/bash_history.rb b/bash_history.rb index 2872a12..ec5bd87 100755 --- a/bash_history.rb +++ b/bash_history.rb @@ -7,8 +7,9 @@ require 'yaml' class BashHistory attr_reader :db OPTIONS = { - :file => File.expand_path("~/.bash_history"), - :archive_file => File.expand_path("~/.bash_history.db"), + :file => File.expand_path("~/.bash_history"), + :archive_file => File.expand_path("~/.bash_history.db"), + :time_format => "%F %T", } def initialize(opts = {}) @options = OPTIONS.merge(opts) @@ -20,13 +21,15 @@ class BashHistory def keys; db.keys; end def keys_to_i; keys.map {|i| i.to_i }; end def values; db.map {|k,v| _yl(v) }; end + def values_by_time; db.map {|k,v| _yl(v) }.sort_by {|x| x[:time] } ; end def commands; values.map {|v| v[:cmd] }; end def _yd(data); YAML.dump(data); end def _yl(data); YAML.load(data); end def _md5(data); Digest::MD5.hexdigest(data); end + def _f(v); " %s %s" % [v[:time].strftime(@options[:time_format]), v[:cmd]]; end def find(pat) - values.select {|v| v if v =~ /#{pat}/ } + values.select {|v| v if v[:cmd] =~ /#{pat}/ } end def _parse @@ -36,7 +39,7 @@ class BashHistory l = f.readline.chomp db[_md5(l)] = _yd({:cmd => l, :time => Time.at($1.to_i)}) else - db[_md5(line.chomp)] = _yd({:cmd => line.chomp}) + db[_md5(line.chomp)] = _yd({:cmd => line.chomp, :time => Time.at(0) }) end end end @@ -44,7 +47,7 @@ class BashHistory def render(file) File.open(file,'w+') do |f| values.each do |v| - f.write("#" + v[:time].to_i.to_s + "\n") if v[:time] + f.write("#" + v[:time].to_i.to_s + "\n") if v[:time] and not (v[:time].to_i == 0) f.write(v[:cmd] + "\n") end end @@ -52,8 +55,48 @@ class BashHistory end if $0 == __FILE__ + require 'optparse' + options = {} + OptionParser.new do |opts| + opts.on('--inspect','inspect the data') do |o| + options[:inspect] = o + end + opts.on('-l','--list','list history') do |o| + options[:list] = o + end + opts.on('--fix','fix times') do |o| + options[:fix] = o + end + opts.on('-f','--find PAT','find a command with pattern PAT') do |o| + options[:find] = o + end + end.parse!(ARGV) + bh = BashHistory.new - p bh - p "storing #{bh.keys.count} commands" + if options[:inspect] + p bh + p "storing #{bh.keys.count} commands" + end + if options[:fix] + count = 0 + bh.db.each_pair do |k,v| + yv = bh._yl(v) + if yv[:time].nil? + yv[:time] = Time.at(0) + bh.db[k] = bh._yd(yv) + count += 1 + end + end + puts "fixed [#{count}] times values" + end + if options[:find] + bh.find(options[:find]).sort_by {|x| x[:time]}.each do |val| + puts bh._f(val) + end + elsif options[:list] + bh.values_by_time.each do |val| + puts bh._f(val) + end + end end