EXPAND(1) General Commands Manual Fully-rendered PDF

expand, unexpand(de)tabulate files

expand [-i] [-t width] [file]…
expand [-i] [-t stop,stop[,stop]…] [file]…
unexpand [-af] [-t width] [file]…
unexpand [-af] [-t stop,stop[,stop]…] [file]…

Expands tab characters from each file (standard input stream if "-", the default), in order, writing the result to the standard output stream.

Each character except for the tab is copied verbatim. When a tab is encountered, it's replaced by spaces equal in number to the distance to the next stop; if it's beyond the final defined stop, it's replaced by a single space.

unexpand performs the equivalent processing, but inverse operation, coalescing runs of initial (but see -a) spaces and tabs before each stop into the minimal count of tabs and spaces yielding the same column. No processing is done beyond the final stop.

All characters have the width determined by the current locale, except the tab (the next stop) and backspace (, but not before the first column) Invalid multi-byte character sequences are taken to have null width.

, --tabs=width
Lay out stops every width (default 8).
, --tabs=stop,stop[,stop]…
Set stops at the specified columns. Each stop must be further than the last. stops may be separated by the commas, spaces, and tabs. May also be specified as -t stop -t stop [-t stop]….

, --initial
Only expand tabs if they were preceded by exclusively blanks.

, --all
Also coalesce runs of at least two spaces-or-tabs after the first non-space-or-tab. Implied by -t.
, --first-only
Override -at, only coalesce initial spaces-or-tabs.

Align tab-separated data:

$ printf '147.312$\t12$\t12\t2.3%%\n11 520$\t320$\t30\t20%%\n' | expand
147.312$        12$     12      2.3%
11 520$ 320$    30      20%

$ printf '147.312$\t12$\t12\t2.3%%\n11 520$\t320$\t30\t20%%\n' | expand -t 12
147.312$    12$         12          2.3%
11 520$     320$        30          20%

Tabulate a simple form:

$ {
>    echo Groceries for February:
>    printf '\tBananas\t3.5kg\t$4.51\n'
>    printf '\tKiwis\t2kg\t$3.19\tCall Siegfried to explain short!\n'
>    printf '\tBread\t\t$20.21\n'
> } | expand -t 4,15,25,35
Groceries for February:
    Bananas    3.5kg     $4.51
    Kiwis      2kg       $3.19     Call Siegfried to explain short!
    Bread                $20.21

wcwidth(3), locale(7)

Conforms to IEEE Std 1003.1-2024 (“POSIX.1”); unexpand is "unclear" (Re: unexpand/OPTIONS/-t, STDOUT (&a.) says <space>, which contradicts the <blank> used elsewhere?) on whether folding together non-space blanks is allowed — this implementation doesn't. This appears to be compatible with FreeBSD and the illumos gate. -i and --first-only are extensions, originating from the GNU system. -f and non-decimal stops are extensions.

expand appeared in 1BSD as expand (VI)

expand - expand tabs to spaces in a file like the ex xpand command
with a SYNOPSIS of
expand [ file ... ]
and a hard 8-column tab.

It becomes fully-formed in 2BSD as expand(UCB):

expand - expand tabs to spaces
with a SYNOPSIS of
expand [ -tabstop ] [ -tab1,tab2,...,tabn ] [ file ... ]
allowing up to decimal tabs interspersed between files.

4.1cBSD fixes non-increasing tab detection. Besides the legacy syntax, this as present-day.

unexpand appeared in 4BSD, sharing expand(1), now:

expand, unexpand - expand tabs to spaces, or vice versa
as
unexpand [ -a ] [ file ... ]
aborting each line on the first NUL, and, despite being documented as present-day:
If the -a option is given, then tabs are inserted whenever they would compress the resultant file by replacing two or more characters.
each tab is treated as its equivalent amount of spaces, so '1234567\ta' yields '1234567 a' (i.e. unexpand the tab).

AT&T System V Release 4 UNIX includes 4.2BSD expand and 4.3BSD unexpand in /usr/ucb.

X/Open Portability Guide Issue 4 (“XPG4”) defines expand, marking the -tabstop syntax OB(solescent), and inventing -t, as present-day. It also defines unexpand verbatim (based on the manual, not the implementation — this renders the originating BSD implementation nonconformant)! adding -t, as present-day, for internationalisation and FORTRAN. Both are part of the User Portability Utilities feature group, and for both, the input is specified to be text files, so wonky NUL handling is allowed (well, the behaviour is unspecified, since text files don't contain NULs).

Version 3 of the Single UNIX Specification (“SUSv3”) removes the obsolete syntax from expand.

IEEE Std 1003.1-2008 (“POSIX.1”) moves [un]expand to the base spec, since its User Portability Utilities are exclusively interactive.

July 7, 2024 voreutils 5a9f9f29