Two uses of fmt

December 31, 2013

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

Written on 31 December 2013.
« Reversing my view on Python 3 for new general code: avoid it
Python 3's core compatibility problem and decision »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Dec 31 23:31:01 2013
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.