Using printf in Bash

C++ and other developers will already be familiar with printf as a great way to format the output of text when programming. To have the same tool available in Bash is of great benefit. printf allows you to control and produce complex output formats, just the way you want it. The printf manual page defines printf as a ‘format and print data’ tool, which is exactly what it is and does.

For example, would you like to print a decimal based number with an exact length of 3 bytes (or characters/numbers) for the integer part (the part before the decimal dot or comma, depending on where in the world you live and what your locale is) and 2 bytes (or characters/numbers) for the decimal part of the number? No problem, printf can do it and much more. It could also output the text to a specific column on the screen, etc.

Though the syntax of printf, for a new developer, may look confusing or complex, it is actually quite straightforward. There are only a limited set of commonly employed formatting characters which can be used within a printf output definition. Let’s have a look at these first.

Syntax: printf

These are the most commonly used printf syntax number formatting idioms:

Next, it is good to know how to specify specific options in connection with these formatting idioms. The format for specifying options for these is as follows:

Examples: printf

So for example, to have a float with a width of 3, and a precision of 2, you would specify:

Let’s look at an example:

Straightforward and easy. Note that we could have used a variable instead of “100.304”:

Note also how we added a newline by using a n newline sequence. For a full list of available interpreted sequences, see man printf. The most common ones are n for newline, t for tab and \ for a backslash.

In the options format above we also saw how we can specify flags. There are a limited amount of common flags:

Thus, for example, we can have:

Here we used two variables, and separated the output by two tabs using two t tab sequences. We also inserted a space (as a flag) in between % and the width definition. This led to the negative number in VAR1 to be printed using a negative sign. If the number would have been positive, no sign would have been printed, and instead a space would be printed in the same position.

Finally we used the + flag and indeed our number is output with a leading + sign irrespective of the fact that the number is already positive and thus (normally) no sign would be printed.

So how can we ensure that we have leading zeros or spaces, while still having a specific length? First, we have to ensure our definition width is longer then variable contents, and secondly we can use the 0 flag to show leading zeros:

In this example, we print 3 lines, separated two times by the n newline sequence. We immediately note that if there is no newline at the end of the output, that our Bash prompt returns specifically at the end of our 3rd line of output.

This may not be a nice or handy format in interactive mode in the terminal, but from within a script (think for example about a sequence like 1…2…3… which builds step by step on the screen as progress within the code is made) this can be very handy.

In the second line of output, we use the 0 flag to indicate we would like to use leading zeroes for VAR2. The output indeed yields leading zeroes, up to the defined length.

In the first line of output, we inserted a space whereas in the third line of output (both printing the VAR1 variable) we did not. The output is the same, which is the only oddity I ever found while working with printf; one would expect there to be one additional character given the printf space flag definition. This remains the same even if we would use leading zeroes. It also remains the same if no length is specified.

The usability of the space flag may thus in some cases (negative numbers) be limited. This is not the case for positive numbers:

In this case (positive numbers), the space flag works as expected, and an extra space is inserted in the case of the first VAR1 output.

Conclusion

Using printf from within Bash scripts or at the command line can yield clear well-defined output. If you scale variables correctly (and perhaps range check them for certainty), using printf will give you a flexible method to format the output (and overall screen layout for larger applications) as you choose.

In this article we look at commonly used number formatting idioms, how to define the width of both the integer and decimal part of numbers, and reviewed the most commonly used flags in printf. Enjoy printing well-formatted data with printf!