6

I typically use column to convert input into a table, eg:

$ echo 'a\tb\tc\nd\te\tf' | column -t -s $'\t'
a  b  c
d  e  f

However it collapses empty columns eg:

$ echo 'a\tb\tc\nd\t\tf' | column -t -s $'\t'
a  b  c
d  f

Rather than printing an empty column when there are consecutive delimiters. This is what I would like, using column or otherwise:

a  b  c
d     f
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
tekumara
  • 161
  • 1
    Instead of echo try printf – Romeo Ninov Jan 23 '19 at 11:53
  • 3
    The questioner is clearly using a shell where -e is implied. We have a whole family of duplicate Q&As about that, starting from https://unix.stackexchange.com/questions/65803/ . But that is not the focus of this question, which is about the column command. Imagine that the input of the column command is whatever is necessary to yield TAB-delimited fields within LF-delimited records, some of which are empty. – JdeBP Jan 23 '19 at 12:14

3 Answers3

8

If you use GNU column:

-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.

printf 'a\tb\tc\nd\t\tf\n'  | column -t -n -s $'\t'

Output:

a  b  c
d     f

If GNU column is not available, you can use sed to add a space (or something else, e.g. a -) between the tabs:

printf 'a\tb\tc\nd\t\tf\n'  | sed -e ':loop; s/\t\t/\t-\t/; t loop' | column -t -s $'\t'
pLumo
  • 22,565
  • Thanks for the sed suggestion! I'm using Mac OS X so don't have GNU column or GNU sed, so this is what ended up working for me: printf 'a\tb\tc\nd\t\tf\n' | sed -$'s/\t\t/\t-\t/g' | column -t -s $'\t' – tekumara Jan 24 '19 at 03:21
1

I couldnt find the -n option in my column command version, so fixed it using sed:

echo -e 'a\tb\tc\nd\t\tf' | sed 's/\t\t/\t \t/'| column -t -s $'\t'

0

For those without GNU column (e.g. MacOS): be careful about first and last column. If the first column is not the longest, there would be a shift. The loop in the script didn't seem to be needed. I suggest the following pipe: | sed $'s/^\t/-\t/;s/\t\t/\t-\t/g;s/\t$/\t-/' | column -t

paste \
<(printf "a\nb\nc") \
<(printf "1\n2\n3\n4444\n5\n6") \
<(printf "d\ne\nf\ng\nh\ni\nj\nijkl\nk\nl") \
<(printf "X") \
\
| sed $'s/^\t/-\t/;s/\t\t/\t-\t/g;s/\t$/\t-/' | column -t
a  1     d     X
b  2     e     -
c  3     f     -
-  4444  g     -
-  5     h     -
-  6     i     -
-  -     j     -
-  -     ijkl  -
-  -     k     -
-  -     l     -
kemotep
  • 5,280
  • 7
  • 21
  • 36
  • (1) We prefer each answer to be self-contained. Your post does provide enough new information that I support keeping it as a separate answer. However, it does talk about the other answer; you should explicitly say, from the start, that you are critiquing another answer. (2) I don’t understand what you’re saying about “If the first column is not the longest”; can you explain that more clearly? (3) Unless I’m overlooking something, your answer fails when there are three tabs in a row. That’s why the other answer used a loop. – Scott - Слава Україні Jun 28 '19 at 15:33