57

I'd like to use the Unix column command to format some text. I have fields delimited by tabs, but within each field there are also spaces. column delimits on white space (tabs and spaces). How can I make column only use tabs as the delimiter?

I was trying to specify tab as the delimiter using:

cat myfile | column -t -s"\t"
78
column -t -s '\t'

would separate columns on \ and t characters.

column -s \t is the same as column -s t, as the backslash is interpreted as a quoting operator by the shell.

Here you want to pass a real TAB character to column. With ksh93, zsh, bash, mksh, busybox sh or FreeBSD sh:

column -ts $'\t'

Or enter a real tab character by typing Ctrl-V Tab at the shell prompt (within quotes or preceded by a backslash as the tab character is a token separator in the shell syntax just like space), or use "$(printf '\t')" (those double quotes needed to disable the split+glob operator as the tab character also happens to be in the default value of $IFS).

  • 3
    I had to do column -t -s $'\t' as bash seemed to think '\t' mean both \ and t, but $'\t' means a literal tab. Bash stinks – ThorSummoner Jun 21 '16 at 22:11
  • If you need POSIX compliancy (lord help me), please see my answer, which is heavily based on this fantastic answer! – Nick Bull Sep 10 '18 at 14:49
  • This solution worked for me -- the $'\t' makes tab the delimiter. But I'm pretty sure I do awk -F "\t" to use a tab as a delimiter for awk. Why does that work and not here for column? – Mike Dec 7 '18 at 1:38
3

I used the following (only works if your text does not contain |):

cat myfile | tr '\t' '|' | column -t -s '|'

This just replaces tabs with pipes, then uses column with pipes as delimiters.

(I did this because I didn't see anything in Stéphane's answer that worked out-of-the-box in the fish shell. Otherwise, Stéphane's answer seems good.)

2

The -t is for selecting the number of columns you want. Leaving this blank does not change anything. Also, you want white space after the -s so try this out:

cat myfile | column -s \t

  • Thanks. This is close to what I am looking for. However, now all the lines are merged onto one line. How can I keep each line on its own line? – turtle Nov 30 '12 at 10:09
  • By default, column fills rows before columns. You may be interested in pr – lurker Nov 30 '12 at 10:35
1

For POSIX, $'...', as known as ANSI-C escaping, isn't defined.

Instead, you can use $(printf '\t'):

column -t -s "$(printf '\t')"

$(printf '\011') can be used, as 011 (octal representation of decimal 9) is the ANSI code for a horizontal tab character:

column -t -s "$(printf '\011')"

However see commentary below from Stéphane Chazelas as to why this may not be consistent across shell versions.

  • 1
    Note that POSIX doesn't specify what the encoding of TAB is. There are still POSIX systems whose C locale encoding is EBCDIC based where TAB is 5, not 9 like in ASCII. Wherever possible, it's better to refer to characters by name to avoid this kind of issue like with "$(printf '\t')" as shown in my answer. Note that $'...' is planned for inclusion in the next major version of the POSIX specification. – Stéphane Chazelas Sep 10 '18 at 14:53
  • @StéphaneChazelas is $(printf '\t') POSIX? Thank you! – Nick Bull Sep 10 '18 at 14:57
  • 1
    yes – Stéphane Chazelas Sep 10 '18 at 14:59
  • @StéphaneChazelas Thank you so much, I've updated my answer to include your very helpful tip :) – Nick Bull Sep 10 '18 at 15:02

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.