The venerable
fmt
program is not something that I normally think of as a command that I use in my scripts or on the fly pipelines; I usually think of it more as, say, something that I use to reflow paragraphs in
vi
. But it has quietly been making its way into an increasing number of them because it turns out that
fmt
is the easy and lazy way to do two symmetrical things: to word-split lines and to merge 'one word per line' output back to a single line.
Word splitting is straightforward:
somecmd | fmt -1
Every version of
fmt
that I've seen accepts this and does the right thing; you get one word per line after
fmt
.
Word joining is much more annoying and it's all because of GNU coreutils. Real versions of
fmt
accept very large format widths:
/bin/ls -1 | fmt -9999
Unfortunately the GNU coreutils version of
fmt
has a maximum width of 2500 characters. Worse, it has a 'goal' width that defaults to 93% of the actual width, so if you're worried about getting close to that limit you need to use:
/bin/ls -1 | fmt -2500 -g2500
In practice I usually use '
fmt -999
' in command pipelines because my actual output line is going to be nowhere near 999 characters to start with.
(Usually when I'm doing word merging it's because I'm going to take the one line that results and paste it to something else, which imposes a relatively modest line length limit in practice.)
What this points out is that
fmt
is not really the ideal solution to this (and in fact the FreeBSD version of
fmt
also has oddities, such the man page's description of behavior around the
-n
switch). The traditional Unix solution to these problems is
tr
, using it to either turn spaces to newlines or newlines to spaces. The problem for me in practice is that to use
tr
I need to remember or re-derive the octal value of newline (it's \012, by the way) and that is just a bit too much hassle. So I use
fmt
, vague warts and all.
(The other drawback of
tr
is that '
tr " " "\012"'
will have a trailing space and no final newline. Usually this is not a big deal.)
Actually in writing this I've discovered that I'm behind the times. All of the versions of
tr
that I use today will accept
\n
instead of the octal literal. Either there was a day when this wasn't true or I just never read far enough in the
tr
manpage (and had it stick) to notice that particular feature. (I'm probably still going to keep on using
fmt
, though.)