Bash Scripting – Printf Command Explained With Examples

In this article, I am going to explain the basic usage of the Bash printf command with examples in Linux. By the end of this article, you will be comfortable in using the printf command in Bash shell scripting.

Bash printf command

Bash offers two types of commands that can be used to print your output to the terminal. One is the echo command which is mostly used for this purpose. The second is the printf command.

Printf is similar to the printf function in C language but with its own set of features. The main difference between echo and printf command is that printf offers formatting and additional functionalities compared to the echo command.

If you have not used the echo command before, we have a detailed article about it which you should take a look at.

Printf is a shell built-in, but you can also find external command for printf. Builtin takes precedence over external command. You can get this information by running the type command as shown below.

$ type -a printf
printf is a shell builtin
printf is /usr/bin/printf
printf is /bin/printf

For more details about type command, refer the following guide:

If you wish to run the external version of printf, you have to point to the full directory path where the binary resides.

$ printf "Hello Worldn" # SHELL BUILTIN
$ /usr/bin/printf "Hello Worldn" # EXTERNAL VERSION OF PRINTF
Builtin vs external command
Builtin vs external command

Display Bash printf help

As I mentioned in the previous section, printf is bash builtin. You have to open the bash man page and navigate to the printf section.

$ man bash
/printf → presss
Printf help
Printf help

You can also run the following command which will display the help section of printf from the bash man page.

$ man bash | less --pattern='^ *printf +['

Basic form of printf command

Throughout the examples, I will compare the printf with echo command to understand the commonality.

Below is the format for the printf command:

printf [-v var] format [arguments]

Arguments should be passed to printf else it will fail like as shown in the below image.

$ printf
$ echo $?
Printf without arguments
Printf without arguments

Pass an argument and run the printf command again. From the below example you can see I have added n which is the newline character. By default, printf will not add a new line like the echo command, so you have to add n.

$ printf “Linux is fun to work with” # WITHOUT NEW LINE
$ printf “Linux is fun to work withn” # WITH NEW LINE

Printf with newline character
Printf with newline character

Variables and command interpretation

You can enclose any variables or run commands within the printf statement. This behavior is similar to the echo command.

$ VAR1="Linux"
$ printf "$VAR1 is fun to work withn"
Variable and command interpretation
Variable and command interpretation

Suggested read:

Single vs double quotes behaviour

When you enclose your arguments with single quotes the variable and command will be treated as plain text. This is the same behavior in echo command too. You have to enclose the arguments with double quotes if you want the variable and command to be expanded.

$ printf '$VAR1 is fun to work withn'
$ printf 'Today date = $(date)n'
Usage of single quotes
Usage of single quotes

When you pass arguments without quotes, printf will consider only the first word as an argument and print it. So using quotes around printf is necessary.

$ printf Today date = $(date)n
Arguments without quotes
Arguments without quotes

Redirecting and piping the output

By default, printf will send the outputs to stdout (terminal). You can redirect the output to a file using the redirection operator or combine it with the pipe operator for further processing.

# PRINT TO STDOUT
$ printf "Today date = $(date)n"
# REDIRECT TO A FILE
$ printf "Today date = $(date)n" > /tmp/tdy.txt
$ cat /tmp/tdy.txt
# PIPE
$ printf "Today date = $(date)n" | grep -i -o IST
Redirection and piping
Redirection and piping

Related read:

Assigning output to a variable

Sometimes you may wish to store the printf output to a variable and use it later for some processing. Normally you will run the printf enclosed with brackets which will run the command and assign the output to a variable.

$ ZONE=$(printf "Today date = $(date)n" | grep -i -o IST)
$ printf $ZONE
Output assigned to a variable
Output assigned to a variable

Alternatively, you can use the -v flag along with printf to store the output to a variable. You have to pass variable name after -v flag.

$ printf -v # SYNTAX
$ printf -v TIME "Today date = $(date)n"
$ echo $TIME
Store output to variable
Store output to variable

MultiLine printf statement

When you have more than one line to be printed, then you can enclose the text in double-quotes. Similarly, if you have a huge line to be printed as a single line and wish to write the line in multi-line for better code readability, you can use a backslash at the end of each line where the next line will be considered as a continuation to the previous line.

$ printf "n I am running PoP_OS
It is a great OS
With Great featuresn"
$ printf "I am running pop_os 
It is a great OS
With Great featuresn"
MultiLine printf statement
MultiLine printf statement

Backslash escaped characters

You can use the following backslash-escaped characters in printf.

  • Newline character (n)
  • Horizontal tab (t) and Vertical tab (v)
  • Backspace character (b)
  • Carriage return (r)

Let us discuss one by one with examples.

Newline character (n)

We have already seen about new line character (n) in all previous sections. Newline character (n) will add a new line.

$ printf "Today date = $(date)n"
Newline character
Newline character

Horizontal tab (t) and vertical tab(v)

Horizontal and vertical tab characters are used to add tab spaces to your printf arguments.

$ printf "Today date t $(date)n" # HORIZONTAL TAB
$ printf "Today date v $(date)n" # VERTICAL TAB
Horizontal and vertical tab
Horizontal and vertical tab

Backspace character (b)

Backspace character (b) will remove one letter. This is like pressing Backspace key from our keyboard.

$ printf "It's a rainby day..n"
Backspace character
Backspace character

Carriage return (r)

The cursor is set back to the first position when carriage return (r) is used. Whatever comes after r will be replacing the characters from the first position.

$ printf "It's a rainbyr day..n"
Carriage return
Carriage return

Escape backslash character ()

If you wish to escape special characters (n, t, v, b, r) and treat it like a string then prefix it with double backslash ().

$ printf "It's a rain\by\r day..n"
Backslash escape
Backslash escape

Whatever you have seen till now, you can find the same set of operations in the echo command too. If you already know the echo command, by this time you would have got very comfortable with the printf command too.

Printf format specifiers

Format specifiers are a way to substitute value in printf instead of hard-coding the value in printf. There are many letters that are used for substitution and each letter represents a particular data type. When using a specifier you have to prefix it with a % symbol. Let’s see some of the commonly used format specifiers.

String specifier (%s)

If you want to place any strings inside the printf, you have to use %s. Take a look at the below example. I have a printf statement and I want to substitute the value “United” inside the printf. So %s is used which is a string specifier and when you run the command the value “united” will be substituted in place of %s.

$ printf "++ Manchester %s has a strong lineup this season" "United"
String substitution
String substitution

You can pass as many substitution arguments as you want and you have to use the same number of specifiers inside the argument.

$ printf "++ %s %s has a strong lineup this %s" "Manchester" "United" "season"
Substitute multiple arguments
Substitute multiple arguments

What if fewer specifiers and more arguments are used?

Take a look at the below example. I have used just one specifier at the beginning and have passed three arguments (strings) to be substituted. The way printf treats this is, it will start substituting the first argument in the first specifier and the next argument will be again passed to the first specifier since there are no other specifiers. This way there will be three substitutions happening that are actually not correct and the result we want.

$ printf "++ %s United has a strong lineup this Seasonn" "Manchester" "United" "season"
More arguments passed
More arguments passed

There are some use cases where this behavior makes sense. Take a look at the below example. I wish to print a welcome message for some players and passed their names as arguments. Normally you can store the list of names in an array and loop through the array and print the message. But this is an effective way to achieve the result by avoiding the usage of loops.

$ printf "++ Welcome %s to manchester unitedn" "Ronaldo" "Varane" "Jadon Sanchon"
++ Welcome Ronaldo to manchester united
++ Welcome Varane to manchester united
++ Welcome Jadon Sancho to manchester united
Multiple arguments with single specifier
Multiple arguments with single specifier

Signed decimal integer (%d) and Unsigned decimal integer (%u)

To substitute singed integer numbers, use %d.

$ printf ">> Welcome %s to manchester united - You get shirt number - %dn" "Ronaldo" 7 "Varane" 19 "Jadon Sancho" 25
Signed integers
Signed integers

To substitute unsigned integer numbers, use %u.

$ printf "UNSIGNED INTEGER = %un" 10
Unsigned integers
Unsigned integers

If you try to substitute any data type other than integer you will get an error.

$ printf ">> Ronaldo gets no %dn" seven
Substitute wrong data type
Substitute wrong data type

Floating point number (%f)

To substitute floating point numbers, use %f.

$ printf "Integer 100 to floating-point %fn" 100
Floating point substitution
Floating point substitution

Interpreting backslash escape sequence

You can pass backslash escape sequences as arguments and use %b which will interpret and expand the backslash escape sequence.

$ printf "Welcome to %b Manchester united %b" "v" "n"
Backslash escape sequence
Backslash escape sequence

Printf conversion directives

There are optional conversion modifiers that can be used to format your printf outputs.

%[flags][width][.precision]specifier

Width modifier

The width modifier decides the minimum number of characters in conversion. If the number of characters is less, then spaces will be prefixed like as shown below.

$ printf "%10sn" "Ronaldo"
Width modifier
Width modifier

If you take a look at the above image, the specifier (Ronaldo) is 7 characters and I have specified the width to be 10. In this case, it will add spaces to justify width 10.

You can also use flag modifiers to justify the alignment or add zeros instead of spaces. For example, if the output needs to be left-aligned then you can add a hyphen (-) flag modifier.

$ printf "%-10sn" "Ronaldo"
Alignment
Alignment

In the case of integer and floating-point values, you can replace the space with zeros by adding a zero (0) flag modifier.

$ printf "%010d n" 7
Replace space with zeros
Replace space with zeros

Precision modifier

This is an optional parameter that can be used to decide the number of strings, integers, and floating-point positions to be printed. You have to use dot(.) followed by the integer to decide the number of positions to be printed.

Take a look at the below example. I am using a string specifier and set the precision modifier to four.

$ printf "%.7sn" "Ronaldo has joined Manu"
String precision modifier
String precision modifier

Asterisks (*) can be passed instead of precision integer values. Asterisks will accept argument for precision instead of hard-coding the precision value.

$ printf "%.*sn" 7 "Ronaldo has joined Manu"
Asterisks precision modifier
Asterisks precision modifier

Conclusion

We have covered quite a bit of information about Bash printf command in this article. To use the printf comfortably, just practice all the examples given in the article. Printf is much more powerful in formatting than the examples I have shown in this article. If you are comfortable with the basics, depending on the use case you can use printf efficiently.

Related read: