# Lining up delimiter separated text

**URL:** <https://www.ruby-forum.com/t/lining-up-delimiter-separated-text/127375>\
**Category:** Ruby\
**Created:** [January 28, 2008, 6:45pm UTC](https://www.ruby-forum.com/t/lining-up-delimiter-separated-text/127375 "2008-01-28T18:45:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 28, 2008, 6:45pm UTC](https://www.ruby-forum.com/t/lining-up-delimiter-separated-text/127375/1 "2008-01-28T18:45:49Z")

</div>

BEFORE:  
fname ;; lname ;; age ;; sex ;;  
homer ;; simpson ;; 33 ;; male  
maggie;; simpson ;; 03 ;; female  
bart;;simpson;;10;;male

AFTER:  
fname ;; lname ;; age ;; sex  
homer ;; simpson ;; 33 ;; male  
maggie ;; simpson ;; 03 ;; female  
bart ;; simpson ;; 10 ;; male

REQUEST:  
Show a really cool way to change before into after with  
ruby. Cool = fewest lines OR just plain clever.

–thanks

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 28, 2008, 7:14pm UTC](https://www.ruby-forum.com/t/lining-up-delimiter-separated-text/127375/2 "2008-01-28T19:14:51Z")

</div>

On Jan 28, 2008, at 11:44 AM, removed\_email\_address@domain.invalid wrote:

> bart ;; simpson ;; 10 ;; male
> 
> REQUEST:  
> Show a really cool way to change before into after with  
> ruby. Cool = fewest lines OR just plain clever.

This doesn’t perfectly match your output, but it gets close:

#!/usr/bin/env ruby -wKU

def pretty\_print(input, sep = ‘;;’)  
data = input.map { |line| line.chomp.split(/  
\s\*#{Regexp.escape(sep)}\s\*/) }  
sizes = (0…data.first.size).map { |i| data.map { |row|  
row[i].size }.max }

data.inject("") do |output, row|  
output +  
(0…row.size).map { |i| “%-#{sizes[i]}s” % row[i] }.join("  
#{sep} ") + “\n”  
end  
end

puts pretty\_print(\<\<END\_BEFORE)  
fname ;; lname ;; age ;; sex ;;  
homer ;; simpson ;; 33 ;; male  
maggie;; simpson ;; 03 ;; female  
bart;;simpson;;10;;male  
END\_BEFORE

# \>\> fname ;; lname ;; age ;; sex

# \>\> homer ;; simpson ;; 33 ;; male

# \>\> maggie ;; simpson ;; 03 ;; female

# \>\> bart ;; simpson ;; 10 ;; male

**END**

James Edward G. II

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 28, 2008, 7:16pm UTC](https://www.ruby-forum.com/t/lining-up-delimiter-separated-text/127375/3 "2008-01-28T19:16:37Z")

</div>

On Jan 28, 2008, at 6:44 PM, removed\_email\_address@domain.invalid wrote:

> bart ;; simpson ;; 10 ;; male
> 
> REQUEST:  
> Show a really cool way to change before into after with  
> ruby. Cool = fewest lines OR just plain clever.

Modulus whitespace, here’s a solution

records = DATA.readlines.map {|line| line.chomp.split(/\s\*;;\s\*/)}  
max\_widths = records.transpose.map {|col| col.map {|cell|  
cell.length}.max}

records.each do |r|  
format = max\_widths[0…r.size].map {|mw| “%-#{mw}s”}.join(" ;; ")  
puts format % r  
end

**END**  
fname ;; lname ;; age ;; sex ;;  
homer ;; simpson ;; 33 ;; male  
maggie;; simpson ;; 03 ;; female  
bart;;simpson;;10;;male

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 28, 2008, 7:29pm UTC](https://www.ruby-forum.com/t/lining-up-delimiter-separated-text/127375/4 "2008-01-28T19:29:52Z")

</div>

7stud – wrote:

> removed\_email\_address@domain.invalid wrote:
> 
> > BEFORE:  
> > fname ;; lname ;; age ;; sex ;;  
> > homer ;; simpson ;; 33 ;; male  
> > maggie;; simpson ;; 03 ;; female  
> > bart;;simpson;;10;;male
> > 
> > AFTER:  
> > fname ;; lname ;; age ;; sex  
> > homer ;; simpson ;; 33 ;; male  
> > maggie ;; simpson ;; 03 ;; female  
> > bart ;; simpson ;; 10 ;; male
> > 
> > REQUEST:  
> > Show a really cool way to change before into after with  
> > ruby. Cool = fewest lines OR just plain clever.
> > 
> > –thanks
> 
> How about:
> 
> str =\<\<STR  
> fname ;; lname ;; age ;; sex ;;  
> homer ;; simpson ;; 33 ;; male  
> maggie;; simpson ;; 03 ;; female  
> bart;;simpson;;10;;male  
> STR
> 
> str.each("\n") do |line|  
> puts “%-8s%-4s%-8s%-4s%-4s%-4s%-8s” % line.split(/(;;)/).map {|elmt|  
> elmt.strip}  
> end

Or, this might be a little better:

str.each("\n") do |line|  
puts “%-8s%-4s%-8s%-4s%-4s%-4s%-8s” % line.chomp.split(/\s\*(;;)\s\*/)  
end

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [January 28, 2008, 7:21pm UTC](https://www.ruby-forum.com/t/lining-up-delimiter-separated-text/127375/5 "2008-01-28T19:21:45Z")

</div>

removed\_email\_address@domain.invalid wrote:

> BEFORE:  
> fname ;; lname ;; age ;; sex ;;  
> homer ;; simpson ;; 33 ;; male  
> maggie;; simpson ;; 03 ;; female  
> bart;;simpson;;10;;male
> 
> AFTER:  
> fname ;; lname ;; age ;; sex  
> homer ;; simpson ;; 33 ;; male  
> maggie ;; simpson ;; 03 ;; female  
> bart ;; simpson ;; 10 ;; male
> 
> REQUEST:  
> Show a really cool way to change before into after with  
> ruby. Cool = fewest lines OR just plain clever.
> 
> –thanks

How about:

str =\<\<STR  
fname ;; lname ;; age ;; sex ;;  
homer ;; simpson ;; 33 ;; male  
maggie;; simpson ;; 03 ;; female  
bart;;simpson;;10;;male  
STR

str.each("\n") do |line|  
puts “%-8s%-4s%-8s%-4s%-4s%-4s%-8s” % line.split(/(;;)/).map {|elmt|  
elmt.strip}  
end

–output:–  
fname ;; lname ;; age ;; sex  
homer ;; simpson ;; 33 ;; male  
maggie ;; simpson ;; 03 ;; female  
bart ;; simpson ;; 10 ;; male
