0

I can't fully understand how the -t parameter of the expand command work. Below is an excerpt from its manpage.

NAME
       expand - convert tabs to spaces
...

-t, --tabs=N
       have tabs N characters apart, not 8

What exactly does have tabs N characters apart mean? I did some testing.

root@u2004:~# printf "a\tb\n"
a   b
root@u2004:~# printf "a\tb\n" | od -a
0000000   a  ht   b  nl
0000004
root@u2004:~# printf "a\tb\n" | expand | od -a
0000000   a  sp  sp  sp  sp  sp  sp  sp   b  nl
0000012
root@u2004:~# printf "a\tb\n" | expand -t 4 | od -a
0000000   a  sp  sp  sp   b  nl
0000006
root@u2004:~# printf "a\tb\n" | expand -t 5 | od -a
0000000   a  sp  sp  sp  sp   b  nl
0000007
root@u2004:~#

As you can see, when I pass -t 4, the tab was replaced to 3 spaces. So, in reality, "have tabs 4 characters apart" just means tabs were replace with 3 spaces? I can't understand. Btw, I'm not a native English speaker and it's possible that this is an English related question.

1 Answer 1

2

It refers to tab stops, the positions where the tab jumps to. With -t 4, there's a tab stop every four characters.

A tab doesn't insert a fixed number of spaces, but jumps to the next such position, so the amount of spaces added depends on how long the text before the tab was. E.g.:

$ printf "1\tx\n" | expand -t 4 | od -a
0000000    1  sp  sp  sp   x  nl                                        
0000006
$ printf "123\tx\n" | expand -t 4 | od -a
0000000    1   2   3  sp   x  nl                                        
0000006

The point of course is to get the columns to line up:

$ printf "123\tx\n1\tx\n" |expand -t4
123 x
1   x

So, to try to represent it visually, the tab-stop placement there is like this, with ^ showing the stops:

123412341234...
^   ^   ^

(Of course you can't tab to the very start, so the first one isn't really there.)

That gets messed up if one field is longer than the tab-stop distance, though, but expand takes a list of column positions as an alternative, e.g. this has a four-wide column and an eight-wide column:

$ printf "%b\n" 'A\t1234567\thello' 'B\t987\tworld' |expand  -t4,12
A   1234567 hello
B   987     world

There, the stops are like so:

          11111111112
012345678901234567890...
A   1234567 hello
B   987     world
    ^       ^

I started the numbering from zero there, so that the positions match the numbers given on the command line.

3
  • Thank you for the answer! It's much clearer now. For POSIX compliant tools, normally, how many characters are used for a tabstop? Commented Apr 15, 2022 at 11:23
  • 1
    @FajelaTajkiya, hmm, I'm not sure how many places it would come up in. expand (and unexpand) default to 8, but other than that, I think it mostly comes up when printing to the terminal. And that's up to the terminal settings. (I would expect full-screen editors to deal with tabs themselves, again, by configuration). But for the usual text-processing tools (awk, cut, sed, shell language functions, whatever), the tab is just a single character, mostly like space. Commented Apr 15, 2022 at 11:58
  • Thanks again for the insights! Commented Apr 15, 2022 at 11:59

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.