Skip to content

Instantly share code, notes, and snippets.

@thinkerbot
Created August 24, 2012 19:33
Show Gist options
  • Save thinkerbot/3454779 to your computer and use it in GitHub Desktop.
Save thinkerbot/3454779 to your computer and use it in GitHub Desktop.
Print segments of files at the same location.
#!/usr/bin/env ruby
begin
require 'optparse'
offset=0
length=-1
lineno=nil
quiet=false
OptionParser.new do |opts|
opts.banner = %{
Usage: #{$0} [options] FILES...
Print segments of files at the same location. Use the -c option to integrate
with cmp.
echo abc > a
echo aBc > b
cmp a b | slice -c
0 bc
0 Bc
Options:
}.lstrip
opts.on("-c", "--cmp-ouput", "show slice as per cmp output") do
line = $stdin.gets
case line
when /^(\S+) (\S+) differ: char (\d+), line (\d+)/
ARGV << $1 << $2
offset = $3.to_i - 1
when ""
raise "no differences to show"
else
raise "input does not match expected cmp output -- -c cannot be used:\n#{line.inspect}"
end
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-l", "--length LENGTH", Integer, "bytes to show (default reads to EOL)") do |value|
length = value.to_i
end
opts.on("-L", "--line LINENO", Integer, "offset to line (override -o)") do |value|
lineno = value.to_i
end
opts.on("-o", "--offset OFFSET", Integer, "bytes to offset (default #{offset}, cumulative)") do |value|
offset += value.to_i
end
opts.on("-q", "--quiet", "do not print line/pos, usually MUCH quicker") do
quiet = true
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
end.parse!
ARGV.each do |file|
File.open(file == '-' ? 0 : file) do |io|
line_number = 0
if lineno
lineno.times { io.readline }
line_number = lineno
elsif offset > 0
if quiet
io.pos = offset
else
chunk_size = 1024
(offset / chunk_size).times { line_number += io.read(chunk_size).count("\n") }
line_number += io.read(offset % chunk_size).to_s.count("\n")
end
end
pos = io.pos
content = length < 0 ? io.readline.chomp("\n") : io.read(length)
if quiet
puts content
else
puts "%d@%d %s" % [line_number, pos, content]
end
end
end
rescue Interrupt
exit 130
rescue Errno::EPIPE
exit 0
rescue
raise if $DEBUG
$stderr.puts $!.message
exit 1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment