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 World\n" # SHELL BUILTIN
$ /usr/bin/printf "Hello World\n" # EXTERNAL VERSION OF PRINTF
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
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 $?
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 with\n" # WITH NEW LINE
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 with\n"
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 with\n'
$ printf 'Today date = $(date)\n'
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
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
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
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 TIME "Today date = $(date)\n" $ echo $TIME
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 features\n"
$ printf "I am running pop_os \
It is a great OS \
With Great features\n"
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"
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
Backspace character (\b)
Backspace character (\b
) will remove one letter. This is like pressing Backspace key from our keyboard.
$ printf "It's a rain\by day..\n"
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 rain\by\r day..\n"
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 backslashes (\\
).
$ printf "It's a rain\\by\\r day..\n"
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"
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"
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 Season\n" "Manchester" "United" "season"
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 united\n" "Ronaldo" "Varane" "Jadon Sancho\n" ++ Welcome Ronaldo to manchester united ++ Welcome Varane to manchester united ++ Welcome Jadon Sancho to manchester united
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 - %d\n" "Ronaldo" 7 "Varane" 19 "Jadon Sancho" 25
To substitute unsigned integer numbers, use %u
.
$ printf "UNSIGNED INTEGER = %u\n" 10
If you try to substitute any data type other than integer you will get an error.
$ printf ">> Ronaldo gets no %d\n" seven
Floating point number (%f)
To substitute floating point numbers, use %f
.
$ printf "Integer 100 to floating-point %f\n" 100
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"
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 "%10s\n" "Ronaldo"
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 "%-10s\n" "Ronaldo"
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
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 "%.7s\n" "Ronaldo has joined Manu"
Asterisks (*
) can be passed instead of precision integer values. Asterisks will accept argument for precision instead of hard-coding the precision value.
$ printf "%.*s\n" 7 "Ronaldo has joined Manu"
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:
- Bash Scripting – Indexed Array Explained With Examples
- Bash Scripting – Associative Array Explained With Examples
- Bash Scripting – While And Until Loop Explained With Examples
- Bash Scripting – For Loop Explained With Examples
- Bash Scripting – Functions Explained With Examples
- Bash Heredoc Tutorial For Beginners