Using the printf Command in Bash/Shell, With Examples

Bash printf Command

This article will show you some practical examples for using the printf command in the Bash/Shell on Linux.

The printf command outputs text much like the echo command does – but it allows for more control over the output formatting.

It’s a useful tool for generating your own formatted text output – especially if you need to embed variables in text, include newlines, align and format text, and even display converted values.

printf Syntax

The printf command has the following syntax:

printf [-v var] format [arguments]...

Note that:

  • The -v option tells printf to store the result in the variable var rather than printing it
  • format is a string containing a combination of three different values:
    • Normal characters which will be printed verbatim
    • Backslash-escaped characters which are interpreted before being printed
    • Conversions that are specified and replaced with their respective arguments (think of them a bit like variables)
  • arguments will be passed to the format and used in any defined conversions
    • If more arguments than conversion specifiers are present in the format, the format string is repeated until all arguments have been used
    • If fewer arguments are present, numeric specifiers are set to zero, and string specifiers are set to null

printf Escaped Characters, Conversions, and Flags

printf has a huge collection of options which can be passed to it to make it format text in a myriad of ways. The examples below will show you some practical applications.

Rather than list every option that can be passed to the command here, you can view the full user manual for the printf command on your system by running:

man printf

printf Bash/Shell Examples

Right, so what is all of that actually good for?

Displaying the Rounded Values of Numbers

First, a simple scenario – you want to format a number to two decimal places to display:

printf "%.2f" 4.21423557

This will output:

4.21

The specified format %.2f tells printf to format the number to two decimal places. This is done using the precision directive, which is the . (period) in the format.

This will round the number rather than truncating it to the given number of decimal places. The rounding of floating-point numbers is weird – so check your output!

Rounding Weirdness

To illustrate this weirdness, consider the following:

printf "%.2f" 4.215

It should be 4.22, right? Wrong. In the zsh implementation of printf, it will be rounded to:

4.21

To confirm that the number is actually being rounded, we can check a different value:

printf "%.2f" 4.216

Which will return:

4.22

… so the number being passed to printf is being rounded.

So why does the rounded value of 4.215 appear to be wrong? To put it simply, as it is a floating-point number, the imprecision is caused by a disparity between the value displayed and the value used by the computer in calculations.

There are ways around this, but it is outside the scope of this article – I’ll cover it in another.

Converting Values (Decimal, Hexadecimal, Octal)

A common scenario – you want to display some numbers in a format other than which they were supplied by another program or script. printf can do this using its conversion specification syntax:

printf "Decimal: %d\nHexadecimal: %x\nOctal: %o\n" 64 64 64

This will output:

Decimal: 64
Hexadecimal: 40
Octal: 100

The number 64 is passed to the formatter 3 times and displayed in three different formats.

Making Pretty Output

The below example outputs a formatted table using printf – I’ll explain as we go in the comments, so it’s clear what’s going on:

#/bin/bash

# Define the format for the header text
# This is a new line (\n) followed by a left-aligned string of 15 characters (%-15s), followed by a string of 15 characters (%15s), finally followed by a string of 10 characters (%10s) and another newline
header_format="\n %-15s %15s %10s\n"

# Define the format for the data in each row
# The first two entries mirror those in the header, but the final one is a bit different - a floating number with 2 decimal places(%11.2f) 
row_format=" %-15s %15s %11.2f\n"

# Use the printf command to print the header
# The format is specified, and the arguments containing the column names for the table are supplied
# printf will take the header_format, and insert the values from the attributes into it, formatted to the given specification, then print it
printf "$header_format" "CAR BRAND" "COLOUR" "TOP SPEED"

# Print the horizontal line under the table header
# Here, printf is used to print an equals symbol.  Brace expansion (the curly braces) is a shell scripting shortcut which will run the printf command for every number between 1 and 50, repeating the symbol 50 times to create a line
printf '=%.0s' {1..50}

# Print each row of data using the row_format.  Each line (indicated by a backslash and a line return) contains three values - the car brand, colour, and top speed
# Any value with a space needs to be quoted as values are separated by spaces and printf won't be able to tell where one value ends and another begins
printf "$row_format" \
Toyota Blue 100 \
Ford "Light Green" 78.3875 \
"General Motors" Purple 15.96

Running this script will output:

CAR BRAND                COLOUR  TOP SPEED
==================================================
Toyota                     Blue      100.00
Ford                Light Green       78.39
General Motors           Purple       15.96

Take a careful look at how the data has been formatted by printf here. Where strings of a certain character length were specified for the header and the rows, the text aligns. The top speeds have been formatted to two decimal places and placed in the correct position. Text is right-aligned except where specified for the first column.

With a relatively small amount of syntax, hard-to-read data has been turned into useful information.

The Sky’s the Limit

You’ll come up with your own reasons for using printf – building command-line interfaces with pretty menus for scripts, tabulating the results of database queries – it’s a powerful tool to have in your bag, especially if you want to impress someone with a slick-looking shell script rather than just dumping unformatted text on the screen.

 

You can combine printf with other text handling commands in Linux.

SHARE:
nv-author-image

Brad Morton

I'm Brad, and I'm nearing 20 years of experience with Linux. I've worked in just about every IT role there is before taking the leap into software development. Currently, I'm building desktop and web-based solutions with NodeJS and PHP hosted on Linux infrastructure. Visit my blog or find me on Twitter to see what I'm up to.

Leave a Reply

Your email address will not be published. Required fields are marked *