Shell output gets messy once a script needs aligned columns, padded counters, literal percent signs, or data with embedded escape sequences. The printf command in Linux gives you repeatable formatting without relying on echo behavior that can change by shell, which makes it the safer choice for prompts, reports, generated config lines, and pipeline input.
Most Bash sessions use a shell builtin first, with GNU Coreutils available as /usr/bin/printf on full Linux installs. The examples focus on Bash and GNU behavior, call out Bash-only extensions such as -v, and keep portable patterns visible when the same command may run under /bin/sh.
Formatted output often feeds the next shell step. For downstream filtering or stream edits, combine printf with grep command patterns or sed command examples instead of formatting the same data twice.
Understand the printf Command in Linux
The GNU Coreutils printf documentation describes the external utility as printf format [argument]..., while the Bash manual documents the builtin form as printf [-v var] format [arguments]. In an interactive Bash shell, the builtin normally wins unless you explicitly call /usr/bin/printf or use env printf.
The Linux printf(3) manual page is useful background for conversion flags, width, precision, and numeric formatting, but it documents C library functions such as printf() and snprintf(). Shell printf borrows the same formatting idea while adding command-specific behavior such as format reuse and, in Bash, -v.
printf Command Syntax
printf FORMAT [ARGUMENT...]
The syntax has two moving parts:
- FORMAT: The control string. It can contain ordinary text, backslash escapes such as
\n, and conversion specifications such as%s,%d, or%.2f. - ARGUMENT…: Values consumed by the format string. Each conversion specification uses the next argument, and the format repeats when extra arguments remain.
The command does not append a newline by default. Add \n to the format string whenever the output should end cleanly before the next prompt or command output appears.
Check Which printf Command Runs
Use Bash’s type builtin when you need to see whether the shell will use a builtin or an external binary.
type -a printf
Relevant output on a typical Bash system includes:
printf is a shell builtin printf is /usr/bin/printf printf is /bin/printf
That output means plain printf uses the Bash builtin first. Use /usr/bin/printf or env printf only when you need to test the external GNU utility. Keep printf -v for Bash scripts because the external command has no variable-assignment option and treats -v as format text.
Essential printf Format Specifiers by Task
| Task | Format Pattern | What It Does |
|---|---|---|
| Print one string per line | %s\n | Prints each argument as text and ends each record with a newline. |
| Expand escapes inside an argument | %b | Interprets backslash escapes such as \n in the matching argument. |
| Print signed integers | %d or %i | Formats a numeric argument as a signed decimal integer. |
| Print other integer bases | %u, %o, %x, %X | Prints unsigned decimal, octal, lowercase hexadecimal, or uppercase hexadecimal. |
| Control floating-point precision | %.2f | Prints a floating-point number with two digits after the decimal point. |
| Pad or align fields | %04d, %-12s | Adds leading zeros to numbers or left-aligns text inside a fixed field width. |
| Print a literal percent sign | %% | Outputs % without treating it as the start of a conversion. |
| Show shell-reusable quoting | %q | Prints a shell-escaped representation in Bash and GNU printf; do not rely on it in strictly POSIX scripts. |
Practical printf Command Examples
Print Strings and Newlines with printf
Start with %s\n for predictable line-oriented output. The %s conversion treats the argument as text, and \n ends the line.
printf '%s\n' 'backup complete'
backup complete
Use single quotes around the format string when you want the shell to leave backslashes and percent signs alone before printf sees them.
Format Prompts Before the read Command
Interactive scripts often need a prompt without a trailing newline so the user can type on the same line. Pair printf with the read command in Linux for that pattern.
printf 'Enter project name: '
read -r project
printf 'Project saved as: %s\n' "$project"
The first printf call intentionally omits \n. The final call adds it so later terminal output starts on a clean line.
Align Columns with printf Field Widths
Field widths keep status output readable without reaching for a full reporting tool. A minus sign after % left-aligns the field, while a plain width right-aligns it.
printf '%-12s %-8s %5s\n' 'Service' 'State' 'Port' 'nginx' 'running' '443' 'ssh' 'active' '22'
Service State Port nginx running 443 ssh active 22
The format string has three conversions, so printf consumes arguments in groups of three and repeats the same layout for each row.
Pad Numbers with Zeros Using printf
Zero padding is useful for build numbers, sortable filenames, and fixed-width IDs.
printf 'build-%04d\n' 7
build-0007
Here, 04 means the numeric field should be at least four characters wide and padded on the left with zeros when needed.
Format Decimal, Hexadecimal, and Octal Numbers
Use integer conversions when a script needs the same value in different bases, such as permissions, byte masks, or generated identifiers.
printf 'Decimal: %d\nHex: %x\nOctal: %o\n' 255 255 255
Decimal: 255 Hex: ff Octal: 377
The same number can be rendered several ways without changing the original value. Use %X instead of %x when uppercase hexadecimal letters fit the surrounding output better.
Control Floating-Point Precision with printf
Floating-point formats let you round noisy values before showing them to a reader or saving them in a small report.
LC_ALL=C printf 'Disk usage: %.1f%%\n' 73.456
Disk usage: 73.5%
The .1 precision keeps one digit after the decimal point, and %% prints a literal percent sign. Setting LC_ALL=C keeps the decimal point stable in scripts that may run under locales that use a comma for decimals.
Expand Escape Sequences with %b
The %s conversion prints backslashes literally. Use %b only when the argument is supposed to contain escape sequences that printf should interpret.
printf '%b' 'line one\nline two\n'
line one line two
Keep %b away from untrusted input. A string that contains \c can stop output early, and other escapes can change the displayed result in ways that are hard to spot later.
Store Formatted Text in a Bash Variable
Bash adds -v so formatted output can go straight into a shell variable instead of standard output.
printf -v report 'item=%s count=%03d' 'backup' 7
printf '%s\n' "$report"
item=backup count=007
This is cleaner than command substitution for small Bash scripts because it avoids spawning a subshell just to capture formatted text. Do not use -v in portable sh scripts or with /usr/bin/printf.
Advanced printf Command Techniques
Reuse One printf Format Across Many Arguments
When the argument list is longer than the format string expects, printf repeats the format until the arguments are consumed.
printf '<%s>\n' alpha beta gamma
<alpha> <beta> <gamma>
The same rule can surprise you when too few arguments are supplied. String conversions receive an empty string, while numeric conversions receive zero.
printf '%s:%d\n' only
only:0
That behavior is useful for compact loops, but it can hide missing data if a script expected every record to have the same number of fields.
Use Dynamic Width and Precision with printf
An asterisk lets the width or precision come from an argument. That keeps reusable functions flexible when different callers need different output sizes.
printf '%*.*f\n' 8 2 3.14159
3.14
The first argument supplies the width, the second supplies the precision, and the third is the number being formatted. In this example, the final field is eight characters wide with two digits after the decimal point.
Quote Shell Values with printf %q
Bash and GNU printf support %q for showing a value in a shell-reusable form. Bash commonly backslash-escapes simple metacharacters, while GNU /usr/bin/printf may choose another shell-safe quoting style. Treat it as a diagnostic or Bash/GNU scripting tool, not as a POSIX guarantee.
printf '%q\n' 'two words & more'
two\ words\ \&\ more
This is handy when debugging variable contents that include spaces, shell metacharacters, or other characters that would be hard to see in plain output.
Use printf Safely and Portably
Keep printf Format Strings Literal
Data belongs in arguments, not in the format string. If a variable contains a percent sign and you use it as the format, printf may treat part of the data as a conversion.
value='100% ready'
printf "$value\n"
The relevant Bash error line from that pattern looks like this:
bash: printf: `r': invalid format character
You may also see partial literal text such as 100 before or after the error because standard output and standard error can be displayed in different orders. The failure happens when Bash treats the space after % as a printf flag and then rejects r as the conversion character.
Use a fixed format string and pass the variable as an argument.
printf '%s\n' "$value"
100% ready
Quote printf Arguments That May Contain Spaces
The shell expands variables before printf receives them. Quote variable and array expansions so filenames, service names, or labels with spaces remain one argument each.
items=('alpha beta' 'gamma*')
printf '%s\n' "${items[@]}"
alpha beta gamma*
Without the quotes, Bash can split alpha beta into two arguments and may expand gamma* against matching filenames in the current directory.
Use — When the printf Format Starts with a Dash
Bash printf treats a leading dash as a possible option. Add -- before a format string that starts with -.
printf -- '--help\n'
--help
The -- marker ends option parsing, so the next argument is handled as the format string instead of as an option.
Troubleshoot Common printf Command Errors
Output Appears on the Same Line as the Next Prompt
If the next prompt or output attaches to the end of your text, the format string probably lacks a newline.
printf '%s' 'ready'
printf 'NEXT\n'
readyNEXT
Add \n to the format string when you want line-oriented output.
printf '%s\n' 'ready'
ready
printf Reports an Invalid Number
Numeric conversions such as %d, %u, %x, and %f expect numeric input. Bash reports an error when the argument cannot be converted cleanly.
printf '%d\n' abc
bash: printf: abc: invalid number 0
Use %s for labels or mixed text, and validate numeric input before passing it to an integer or floating-point conversion.
printf '%s\n' abc
abc
printf Treats Percent Signs in Data as Format Characters
An unescaped percent sign in the format string starts a conversion. This usually happens when a script passes user data as the format instead of as an argument.
value='100% ready'
printf "$value\n"
The relevant Bash error line looks like this:
bash: printf: `r': invalid format character
You may also see partial literal text such as 100 before or after the error because printf already started writing ordinary text.
Keep the format fixed and use %% only when the literal percent sign is part of the format itself.
printf 'Progress: %d%%\n' 75
Progress: 75%
printf Uses Empty Strings or Zero for Missing Arguments
Missing arguments do not always stop the command. printf fills missing string conversions with an empty string and missing numeric conversions with zero.
printf '%s:%d\n' only
only:0
If that output is not intended, check the number of fields before formatting the record, or split the format across smaller calls where missing data is easier to catch.
printf Rejects a Format That Starts with —
Without an option terminator, Bash can treat a leading -- in the format as an invalid option.
printf '--help\n'
bash: printf: --: invalid option printf: usage: printf [-v var] format [arguments]
Add -- before the format string.
printf -- '--help\n'
--help
Conclusion
printf is ready for predictable shell output: prompts stay controlled, tables line up, numbers carry the right padding, and data stays separate from the format string. Keep printf '%s\n' as the safe default, then add width, precision, %b, or Bash-only -v only when the script actually needs those behaviors.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><a href="https://example.com">link</a><blockquote>quote</blockquote>