4

I use column -t to format data for easy viewing in the shell, but there seems to be no option to specify column alignment (e.g. align to the right).

Any Bash one-liners to do it? I have arbitrary number of columns.

2

UPDATE: added a script (not a one liner, though) which allows you to choose which columns you want justified... It caters for Left (default) and Right (not Center).. As-is, it expects TAB delimited fields. You can change the column output seperator via $S.

RJustCol=(2 3 5)  # Set columns to be right justified.
RJustRex=; Q=$'\x01'; R=$'\x02'; S=" | "
for r in ${RJustCol[@]} ;do  # Build the Right-justify regex.
  RJustRex="${RJustRex}s/^(([^\t]+\t){$((r-1))})([^\t]+)\t/\1\3$R\t/; "
done
sed -r "s/$/\tZ/g; s/^/$Q/; s/\t/\t$Q/g; $RJustRex" file |
  column -t -s $'\t' | 
    sed -r "s/  $Q/$Q/g; s/$Q([^$Q$R]*)$R([^$Q]*)/$S\2\1/g; s/$Q/$S/g; s/Z$//"

Typical output:

| The Lost Art       |   +1255 |  789 | Los                 |     -55 | 
| of the Idle Moment | -159900 | 0123 | Fabulosos Cadillacs | +321987 | 

Note:column doesn't work as you might expect when you have empty cells.

Option -n
        By default, the column command will merge multiple adjacent
        delimiters into a single delimiter when using the --t option;
        this option disables that behavior. This option is a Debian
        GNU/Linux extension.

From here on is the original answer which is related to but doesn't specifically address tne main issue of th question..

Here is the "one-liner" which suits integers (and allows +/- signs) .. The "X" place-holder forces column to right-pad the last cell.

sed 's/$/\tX/g' file |column -t |sed -r 's/([-+]?[0-9.]+)( +)/\2\1/g; s/^  //; s/X$//'

Typical output

  +1255  789  011      -55       34
-159900   33  022  +321987  2323566

If you have float values, or floats mixed with integers, or just integers, (optional leading +/- signs), a bit more shuffling works.

sed -r 's/$/\tX/; 
        s/([-+]?[0-9]+\.[0-9]+)\t/\1@\t/g
        s/([-+]?[0-9]+)\t/\1.@\t/g
        s/\./\t./g' file |
  column -t |
    sed -r 's/  \././g
            s/([-+]?[0-9.]+)( +)/\2\1/g
            s/\.@/ /g
            s/@//g
            s/ +X$//'

Typical output

+1255       789   0.11   -55           34
  -15.9900   33   0.22  +321.987  2323566
2

From a simple point, I'd use awk

column -t filename | awk '{for (i=0; i<NF; i++){l=index($0, $i)+1;printf "%*s ", index($0, $(i+1))-l, $i}printf "%*s\n", index($0, $NF)-l, $NF}'

This makes for slightly wider

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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