Created
August 24, 2012 19:33
-
-
Save thinkerbot/3454779 to your computer and use it in GitHub Desktop.
Print segments of files at the same location.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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