Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there an easy way to split comma-delimited lines of text into columns with some of the columns right-justified?

As a bonus, it would be nice to format numbers, but this probably isn't too hard with sed.

share|improve this question
add comment

2 Answers 2

up vote 4 down vote accepted

Awk and the %42s printf format comes to mind. Here's a simple script to get you started. Setting width[i] to a positive value in the BEGIN clause makes that column have the given width, left-aligned. If width[i] is negative, then column i is right-aligned and has the width -width[i]. This script doesn't handle wide fields intelligently, all subsequent columns are just shifted right on that line.

awk -F, -vOFS= '
BEGIN {width[1]=-10; width[2]=8;}
{ for (i=1; i<=NF; i++) {$i = sprintf("%*s", width[i], $i)}
  print }'

If you have numeric fields, you can use other printf formats.

If you have the BSD utility column (Debian ships it, I don't know about other Linux distributions), you can easily format things in columns with column -t -s ,. The nice thing about column is that it determines the column width automatically. However, it doesn't do right-hand formatting; while you can get it with some post-processing, I don't know if the complexity is worth it.

You could do everything in Perl. Its format facility may help.

A more powerful approach to table formatting with common unix tools is tbl, which is the part of *roff (the man page formatter) that handles tables. But that's also more complex because you need to convert the input to roff.

Yet another possible tool is the text mode browser w3m, which is good at table rendering. Here, you'd have to convert the input to HTML.

share|improve this answer
    
Thanks +1, do you know why using printf, rather than sprintf, causes problems with printing the next line on the same line (if I have 4 fields, it prints those fields and then the next line right after that before the line break). –  jonderry Apr 22 '11 at 23:43
add comment

Ended up figuring this out myself. Instead of column, use awk to produce columns. For example, if foo.txt has lines of the form "bar,36,17.34566", you could do something like

cat foo.txt | awk -F, '{printf "%-20s %20d %20.2f\n", $1, $2, $3 }'

to produce columns of width 20, with the first column left-justified, the other two columns right-justified, and the last column with two decimal places of precision.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.