Skip to content

Instantly share code, notes, and snippets.

@thinkerbot
Created May 8, 2012 20:09
Show Gist options
  • Save thinkerbot/2638925 to your computer and use it in GitHub Desktop.
Save thinkerbot/2638925 to your computer and use it in GitHub Desktop.
Ruby sprintf from the command line.

sprintf(1) -- reformat text a-la sprintf

SYNOPSIS

sprintf [options] FILES...

DESCRIPTION

Print files using the specified sprintf format. Reads from stdin if no files are specified. Use '-' as a file to specify stdin manually. By default the input is not changed (equivalent to -c).

OPTIONS

These options control how sprintf operates:

  • -b: binary output

  • -c: string output

  • -d: debug mode

  • -f FORMAT: custom format

  • -h, --help: print this help

  • -o: octal output

  • -x: hex output

INSTALLATION

Add sprintf to your PATH (or execute it directly). A nice way of doing so is to clone the repo and add the bin dir to PATH. This allows easy updates via git pull and should make the manpages available via man sprintf.

git clone git://gist.github.com/2638925.git
export PATH="$PATH:$(pwd)/2638925/bin"
#!/usr/bin/env ruby
begin
require 'optparse'
format = "%c"
OptionParser.new do |opts|
opts.banner = %{
Usage: sprintf [options] FILES...
Print files using the specified sprintf format. Reads from stdin if no files
are specified. Use '-' as a file to specify stdin manually. By default the
input is not changed (equivalent to -c).
Options:
}.lstrip
opts.on("-b", "binary output") do
format = "%b"
end
opts.on("-c", "string output") do
format = "%c"
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-f FORMAT", "custom format") do |str|
format = str
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
opts.on("-o", "octal output") do
format = "%o "
end
opts.on("-x", "hex output") do
format = "%x "
end
end.parse!
if ARGV.empty?
ARGV << '-'
end
ARGV.each do |file|
File.open(file == '-' ? 0 : file) do |io|
while b = io.getbyte
print format % b
end
end
end
rescue Interrupt
exit 130
rescue Errno::EPIPE
exit 0
rescue
raise if $DEBUG
$stderr.puts $!.message
exit 1
end
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "SPRINTF" "1" "September 2012" "1.0.0" ""
.
.SH "NAME"
\fBsprintf\fR \- reformat text a\-la sprintf
.
.SH "SYNOPSIS"
\fBsprintf\fR \fIoptions\fR FILES\.\.\.
.
.SH "DESCRIPTION"
Print files using the specified sprintf format\. Reads from stdin if no files are specified\. Use \'\-\' as a file to specify stdin manually\. By default the input is not changed (equivalent to \-c)\.
.
.SH "OPTIONS"
These options control how \fBsprintf\fR operates:
.
.TP
\fB\-b\fR
binary output
.
.TP
\fB\-c\fR
string output
.
.TP
\fB\-d\fR
debug mode
.
.TP
\fB\-f FORMAT\fR
custom format
.
.TP
\fB\-h\fR,\fB\-\-help\fR
print this help
.
.TP
\fB\-o\fR
octal output
.
.TP
\fB\-x\fR
hex output
.
.SH "INSTALLATION"
Add \fBsprintf\fR to your PATH (or execute it directly)\. A nice way of doing so is to clone the repo and add the bin dir to PATH\. This allows easy updates via \fBgit pull\fR and should make the manpages available via \fBman sprintf\fR\.
.
.IP "" 4
.
.nf
git clone git://gist\.github\.com/2638925\.git
export PATH="$PATH:$(pwd)/2638925/bin"
.
.fi
.
.IP "" 0
# Step 0 - write it
#
# ruby sprintf_0.rb
#
File.open("abc.txt") do |io|
while b = io.getbyte
print "%b" % b
end
end
require 'optparse'
# Step 1 - write it with opts and args
#
# ruby sprintf_1.rb -b abc.txt xyz.txt
# ruby sprintf_1.rb abc.txt xyz.txt
#
format = "%c"
OptionParser.new do |opts|
opts.banner = %{
Usage: #{$0} [options] FILES...
Print files using the specified sprintf format. Reads from stdin if no files
are specified. Use '-' as a file to specify stdin manually. By default the
input is not changed (equivalent to -c).
Options:
}.lstrip
opts.on("-b", "binary output") do
format = "%b"
end
opts.on("-c", "string output") do
format = "%c"
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-f FORMAT", "custom format") do |str|
format = str
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
opts.on("-o", "octal output") do
format = "%o "
end
opts.on("-x", "hex output") do
format = "%x "
end
end.parse!
ARGV.each do |file|
File.open(file) do |io|
while b = io.getbyte
print format % b
end
end
end
#!/usr/bin/env ruby
require 'optparse'
# Step 2 - hide the fact this is ruby
#
# chmod +x ./sprintf_2
# ./sprintf_2 abc.txt xyz.txt
#
format = "%c"
OptionParser.new do |opts|
opts.banner = %{
Usage: #{$0} [options] FILES...
Print files using the specified sprintf format. Reads from stdin if no files
are specified. Use '-' as a file to specify stdin manually. By default the
input is not changed (equivalent to -c).
Options:
}.lstrip
opts.on("-b", "binary output") do
format = "%b"
end
opts.on("-c", "string output") do
format = "%c"
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-f FORMAT", "custom format") do |str|
format = str
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
opts.on("-o", "octal output") do
format = "%o "
end
opts.on("-x", "hex output") do
format = "%x "
end
end.parse!
ARGV.each do |file|
File.open(file) do |io|
while b = io.getbyte
print format % b
end
end
end
#!/usr/bin/env ruby
begin
require 'optparse'
format = "%c"
OptionParser.new do |opts|
opts.banner = %{
Usage: #{$0} [options] FILES...
Print files using the specified sprintf format. Reads from stdin if no files
are specified. Use '-' as a file to specify stdin manually. By default the
input is not changed (equivalent to -c).
Options:
}.lstrip
opts.on("-b", "binary output") do
format = "%b"
end
opts.on("-c", "string output") do
format = "%c"
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-f FORMAT", "custom format") do |str|
format = str
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
opts.on("-o", "octal output") do
format = "%o "
end
opts.on("-x", "hex output") do
format = "%x "
end
end.parse!
ARGV.each do |file|
File.open(file) do |io|
while b = io.getbyte
print format % b
end
end
end
# Step 3 - handle errors gracefully
#
# ./sprintf_3 missing_file
#
rescue
raise if $DEBUG
$stderr.puts $!.message
exit 1
end
#!/usr/bin/env ruby
begin
require 'optparse'
format = "%c"
OptionParser.new do |opts|
opts.banner = %{
Usage: #{$0} [options] FILES...
Print files using the specified sprintf format. Reads from stdin if no files
are specified. Use '-' as a file to specify stdin manually. By default the
input is not changed (equivalent to -c).
Options:
}.lstrip
opts.on("-b", "binary output") do
format = "%b"
end
opts.on("-c", "string output") do
format = "%c"
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-f FORMAT", "custom format") do |str|
format = str
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
opts.on("-o", "octal output") do
format = "%o "
end
opts.on("-x", "hex output") do
format = "%x "
end
end.parse!
# Step 4 - handle stdin as a file
#
# cat abc.txt | ./sprintf_4 - xyz.txt
#
ARGV.each do |file|
File.open(file == '-' ? 0 : file) do |io|
while b = io.getbyte
print format % b
end
end
end
rescue
raise if $DEBUG
$stderr.puts $!.message
exit 1
end
#!/usr/bin/env ruby
begin
require 'optparse'
format = "%c"
OptionParser.new do |opts|
opts.banner = %{
Usage: #{$0} [options] FILES...
Print files using the specified sprintf format. Reads from stdin if no files
are specified. Use '-' as a file to specify stdin manually. By default the
input is not changed (equivalent to -c).
Options:
}.lstrip
opts.on("-b", "binary output") do
format = "%b"
end
opts.on("-c", "string output") do
format = "%c"
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-f FORMAT", "custom format") do |str|
format = str
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
opts.on("-o", "octal output") do
format = "%o "
end
opts.on("-x", "hex output") do
format = "%x "
end
end.parse!
# Step 5 - handle stdin by default
#
# cat abc.txt xyz.txt | ./sprintf_5
#
if ARGV.empty?
ARGV << '-'
end
ARGV.each do |file|
File.open(file == '-' ? 0 : file) do |io|
while b = io.getbyte
print format % b
end
end
end
rescue
raise if $DEBUG
$stderr.puts $!.message
exit 1
end
#!/usr/bin/env ruby
begin
require 'optparse'
format = "%c"
OptionParser.new do |opts|
opts.banner = %{
Usage: #{$0} [options] FILES...
Print files using the specified sprintf format. Reads from stdin if no files
are specified. Use '-' as a file to specify stdin manually. By default the
input is not changed (equivalent to -c).
Options:
}.lstrip
opts.on("-b", "binary output") do
format = "%b"
end
opts.on("-c", "string output") do
format = "%c"
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-f FORMAT", "custom format") do |str|
format = str
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
opts.on("-o", "octal output") do
format = "%o "
end
opts.on("-x", "hex output") do
format = "%x "
end
end.parse!
if ARGV.empty?
ARGV << '-'
end
ARGV.each do |file|
File.open(file == '-' ? 0 : file) do |io|
while b = io.getbyte
print format % b
end
end
end
# Step 6 - gracefully handle interrupt
#
# yes | ./sprintf_6 > /dev/null # ctrl-c
# echo $? # 130
#
# * [POSIX Spec](http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html)
# * [Advanced BASH scripting guide](http://tldp.org/LDP/abs/html/exitcodes.html)
#
rescue Interrupt
exit 130
rescue
raise if $DEBUG
$stderr.puts $!.message
exit 1
end
#!/usr/bin/env ruby
begin
require 'optparse'
format = "%c"
OptionParser.new do |opts|
opts.banner = %{
Usage: #{$0} [options] FILES...
Print files using the specified sprintf format. Reads from stdin if no files
are specified. Use '-' as a file to specify stdin manually. By default the
input is not changed (equivalent to -c).
Options:
}.lstrip
opts.on("-b", "binary output") do
format = "%b"
end
opts.on("-c", "string output") do
format = "%c"
end
opts.on("-d", "debug mode") do
$DEBUG = true
end
opts.on("-f FORMAT", "custom format") do |str|
format = str
end
opts.on("-h", "--help", "print this help") do
puts opts
puts
exit
end
opts.on("-o", "octal output") do
format = "%o "
end
opts.on("-x", "hex output") do
format = "%x "
end
end.parse!
if ARGV.empty?
ARGV << '-'
end
ARGV.each do |file|
File.open(file == '-' ? 0 : file) do |io|
while b = io.getbyte
print format % b
end
end
end
rescue Interrupt
exit 130
# Step 7 - gracefully handle closed pipe:
#
# yes | ./sprintf_7 | ruby -e '$stdin.close'
# echo $? # 0
#
rescue Errno::EPIPE
exit 0
rescue
raise if $DEBUG
$stderr.puts $!.message
exit 1
end
Step 8 - add to path
cd ..
which sprintf
export PATH="$PATH:$(pwd)/bin"
which sprintf
sprintf -h
Step 9 - Add a man page
Use ronn:
git clone git://github.com/rtomayko/ronn.git
Correction, use a fork of ronn:
git clone git://github.com/thinkerbot/ronn.git
mkdir -p man/man1
ruby -Ironn/lib ronn/bin/ronn -r --pipe README.md > man/man1/sprintf.1
Optionally release info:
ruby -Ironn/lib ronn/bin/ronn -r --pipe --organization="$(VERSION)" --date="$(DATE)" README.md > man/man1/sprintf.1
Now:
man sprintf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment