How-tos

How to Use printf in Bash – CloudSavvy IT


Shutterstock/gilangtristiano

Text formatting is an interesting topic, especially when it comes to Bash. Whilst there are many tools for text formatting, printf is unique and universal. Learn all about printf in Bash to format your text just the right way!

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:

%d or %i  a signed decimal integer
%u        an unsigned decimal integer
%f        a decimal floating point number
%e        a scientific notation number
%g        will let printf use %e or %f, whichever is shorter
%c        a single character
%s        a string of characters
%%        a literal '%'

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:

%[flag(s)][width][.precision][length]number_formatting_idiom

Examples: printf

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

%3.2f

Let’s look at an example:

printf "%3.2fn" "100.304" 

Printing a well formatted float with printf

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

VAR1=100.304
printf "%3.2fn" ${VAR1}

Printing a formatted float with printf using a Bash variable

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:

-   Left-justify text (right-justify is the default)
+   Forces the use of a sign, even if positive
' ' A space is inserted if no sign will be used
0   Left-pad the number with zeroes instead of spaces when padding is specified

Thus, for example, we can have:

VAR1=-100.304
VAR2=100.304
printf "% 3.2ftt%+3.2fn" ${VAR1} ${VAR2}

Printing negative numbers with printf and formatting

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:

VAR1=-100.304
VAR2=100.304
printf "% 13.2fn%013.2fn%13.2f" ${VAR1} ${VAR2} ${VAR1}

Output formatting for printf and leading zeroes definition

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:

VAR1=100.304
printf "% fn%0fn" ${VAR1} ${VAR1}

A leading space in positive numbers based on the special space flag

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!



READ SOURCE

This website uses cookies. By continuing to use this site, you accept our use of cookies.