Typically, when writing bash scripts, we use
echo to print to the standard output.
echo is a simple command but is limited in its capabilities.
To have more control over the formatting of the output, use the
printf command formats and prints its arguments, similar to the C
printf is a shell builtin in Bash and in other popular shells like Zsh and Ksh. There is also a standalone
/usr/bin/printf binary, but the shell built-in version takes precedence. We will cover the Bash builtin version of
The syntax for the
printf command is as follows:
printf [-v var] format [arguments]
-v option tells
printf not to print the output but to assign it to the variable.
format is a string which may contain three different types of objects:
- Normal characters that are simply printed to the output as-is.
- Backslash-escaped characters which are interpreted and then printed.
- Conversion specifications that describe the format and are replaced by the values of respective arguments that follow the format string.
The command accepts any number of
arguments. If more
arguments than format specifiers are provided, the
formatstring is reused to consume all of the arguments. If fewer
arguments than format specifiers are supplied, the extra numeric-format specifiers are set to zero value while string-format specifiers are set to null string.
Below are a few points to consider when passing arguments the
- The shell will substitute all variables, wildcard matching, and special characters before passing the arguments to the
- When using single quotes
''the literal value of each character enclosed within the quotes will be preserved. Variables and commands will not be expanded.
A typical example of using
printf looks like:
printf "Open issues: %s\nClosed issues: %s\n" "34" "65" Open issues: 34 Closed issues: 65
Open issues: %s\nClosed issues: %s\n is the
format while “34” and “65” are arguments. The format string contains two newline characters (
\n) and two format specifiers (
%s) that are replaced with the arguments.
printf command doesn’t add a newline character (
\n) at the end of the line.
The backslash-escaped characters are interpreted when used in the format string or in an argument corresponding to a
%bconversion specifier. Here is a list of the most common escape characters:
\\– Displays a backslash character.
\b– Displays a backspace character.
\n– Displays a new line.
\r– Displays a carriage return.
\t– Displays a horizontal tab.
\v– Displays a vertical tab.
A conversion specification takes the following form:
Each conversion specification stars with the percent sign (
%), includes optional modifiers and ends with one of the following letters that represent the data type (
specifier) of the corresponding argument:
Type conversion specifier
The type conversion
specifier is a character that specifies how to interpret the corresponding argument. This character is required, and it is placed after the optional fields.
Below is a list showing all type conversions and what they do:
%b– Print the argument while expanding backslash escape sequences.
%q– Print the argument shell-quoted, reusable as input.
%i– Print the argument as a signed decimal integer.
%u– Print the argument as an unsigned decimal integer.
%o– Print the argument as an unsigned octal integer.
%X– Print the argument as an unsigned hexadecimal integer.
%xprints lower-case letters and
%E– Print the argument as a floating-point number in exponential notation.
%eprints lower-case letters and
%A– Print the argument as a floating-point number in hexadecimal fractional notation.
%aprints lower-case letters and
%G– Print the argument as a floating-point number in normal or exponential notation, whichever is more appropriate for the given value and precision.
%gprints lower-case letters and
%c– Print the argument as a single character.
%f– Print the argument as a floating-point number.
%s– Print the argument as a string.
%%– Print a literal
An unsigned number represents zero and positive numbers, while a signed number represents negative, zero, and positive numbers.
The following command prints the number 100 in three different number systems:
printf "Decimal: %d\nHex: %x\nOctal: %o\n" 100 100 100 Decimal: 100 Hex: 64 Octal: 144
Flags are the first optional modifiers and are used to set the justification, leading zeros, prefixes, etc.
Here are the most common ones:
-– Left align the printed text within the field. By default, the text is right-aligned.
+– Prefix the numbers with a
-signs. By default, only negative numbers are prefixed with a negative sign.
0– Pads numbers with leading zeros rather than space.
`- Prefix the positive numbers with a blank space and negative numbers with a minus (-`).
#– An alternative format for numbers.
width directive filed is placed after any flag characters and specifies the minimum number of characters the conversion should result in.
If the outputted text width is less than the specified width, it’s padded with spaces. The width can be specified as a non-negative decimal integer or an asterisk (
Here is an example:
printf "%20s %d\n" Mark 305
%20s means set the field at least 20 characters long. Blanks are added before the text because, by default, the output is right-justified. To align the text to left, use the
- flag (
When an asterisk (
*) is used as a
width directive, then the width of the conversion field is set by a width argument that precede the argument that’s being formatted.
In the example below we’re setting the width to 10:
printf "%0*d" 10 5
0 is a flag that pads the number with leading zeros instead of blanks. The output text will have at least 10 characters:
.precision modifier consists of a dot (
.) followed by a positive integer or asterisk (
*) that depending on the specifier type, sets the number of string or digit characters or the number of decimal places to be printed.
The precision has the following effect:
- If the conversion type is an integer, the precision specifies the minimum number of digits to be printed. If the number of digits in the argument is less than precision, leading zeros are printed.
- If the conversion type is a floating-point, the precision specifies the number of digits that follow the decimal-point character. The default precision is 6.
- If the conversion type is a string, the precision specifies the maximum number of characters to be printed. If the number of characters in the argument is greater than precision, the excess characters are truncated.
Here is an example showing how to round a floating-point number to 3 decimals:
printf "%.3f" 1.61803398 1.618
When precision is set to an asterisk (
*), its value is set by the precision argument that precede the argument that’s being formatted.
printf "%.*f" 3 1.61803398 1.618
printf command takes a format and arguments and prints a formatted text.
If you have any questions or feedback, feel free to leave a comment.