'Align around a given character in bash

Is there an easy way to align multiple rows of text about a single character, similar to this question, but in bash.

Also open to zsh solutions.

What I have:

aaa:aaaaaaaa
bb:bbb
cccccccccccc:cc
d:d

What I want:

         aaa:aaaaaaaa
          bb:bbb
cccccccccccc:cc
           d:d

Preferably the output can be piped out and retain its layout too.



Solution 1:[1]

You can try with column and gnu sed

column -t -s':' infile | sed -E 's/(\S+)(\s{0,})(  )(.*)/\2\1:\4/'

Solution 2:[2]

The shell itself does not seem like a particularly suitable tool for this task. Using an external tool makes for a solution which is portable between shells. Here is a simple Awk solution.

awk -F ':' '{ a[++n] = $1; b[n] = $2; if (length($1) > max) max = length($1) }
  END { for (i=1; i<=n; ++i) printf "%" max "s:%s\n", a[i], b[i] }'

Demo: https://ideone.com/Eaebhh

This stores the input file in memory; if you need to process large amount of text, it would probably be better to split this into a two-pass script (first pass, just read all the lines to get max, then change the END block to actually print output from the second pass), which then requires the input to be seekable.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ctac_
Solution 2 tripleee