printf Command: Formatted Output in the Shell

printf Command: Formatted Output in the Shell

What printf Can Do

You are comfortable printing text with echo, but have you ever wished you could line up columns or show exactly two decimal places? That is what the printf command is for.

Quick Summary

  • printf prints text using a format string you control
  • Unlike echo, it does not add a newline automatically (you write \n)
  • Feed values into %s (string), %d (integer), %f (float)
  • Use %5d or %-10s for column alignment, %.2f for decimal places

What You'll Learn

  • The difference between printf and echo, and when to use each
  • The basic form of printf (format string + values)
  • How to use the main format specifiers: %s, %d, %f
  • How to align columns, zero-pad, and set decimal places
  • Escape sequences like \n and \t
  • Common beginner pitfalls

1. How Is printf Different from echo?

Conclusion: echo is handy but its newline and \n handling varies by environment. printf gives you strict, predictable formatting and clean alignment.

Lina: If I just want to print text, isn't echo enough? What does printf add?
Linny-senpai: Good question. echo is handy, but it struggles with fine control like "line these numbers up." It also behaves differently across systems.
Lina: Differently across systems? What do you mean?
Linny-senpai: For example, to print a tab with echo -e "a\tb", some shells or systems ignore -e and print -e a\tb literally. printf has no such inconsistency.
# echo: the meaning of -e varies by environment
echo -e "Name\tScore"

# printf: always prints exactly as the format says
printf 'Name\tScore\n'
Name	Score

When you need precise formatting or stable output in a script, reach for printf. For a quick one-off message, echo is fine.

2. What Is the Basic Form of printf?

Conclusion: The form is printf 'format' values.... Each value fills a %s (and similar) in order, and you add newlines yourself with \n.

Lina: How do I actually write printf?
Linny-senpai: You just put two things side by side: a "format string" and the "values" to pour in. Let's start with %s, which means a string.
Lina: The s in %s stands for string, right?
Linny-senpai: Exactly. Whatever value you write after the format drops into the %s spot.
printf '%s\n' penguin
penguin

The %s in the format string marks "a value goes here." The penguin after it flows into that spot, and the trailing \n adds a newline.

printf never adds a newline for you. If you forget \n, the next shell prompt sticks to the same line. Until you get used to it, always add it.

You can list multiple values by writing as many %s as you need.

printf '%s likes %s\n' Lina Linux
Lina likes Linux

3. How Do You Use Format Specifiers (%s %d %f)?

Conclusion: %s is for strings, %d for integers, %f for floats. Match the specifier to the kind of value.

Lina: Are there others besides %s?
Linny-senpai: The three you'll use most are %s for strings, %d for integers, and %f for floats. Here is a table.
Specifier Meaning Example input Output
%s String abc abc
%d Integer (decimal) 42 42
%f Float (6 digits) 3.14 3.140000
%x Hexadecimal 255 ff
%% A literal % character (none) %
printf '%s costs %d dollars, %f with tax\n' apple 100 110
apple costs 100 dollars, 110.000000 with tax
Lina: Hmm, %f printed 110.000000 with lots of trailing zeros...
Linny-senpai: Without any setting, %f shows six decimal places. I'll show you how to change that in the next section.
Lina: And to print a % itself, I write %%?
Linny-senpai: Right. % is special, so to print it as a literal character you double it.

Passing a float or text to %d produces an error or 0. For instance, printf '%d\n' abc warns that the value is not a number. Always match the value type to the specifier.

4. How Do You Set Width and Precision?

Conclusion: A number between % and the specifier sets the field width; a number after . sets decimal places. Use - for left-align and 0 for zero-padding.

Lina: That 110.000000 from before -- I want it as 110.00.
Linny-senpai: Write %.2f and you get two decimal places. Remember: "the number after the dot is the number of decimals."
printf '%.2f\n' 110
110.00

You can also set the field width (the minimum number of characters), which is great for right-aligning numbers like a table.

printf '%5d\n' 1
printf '%5d\n' 42
printf '%5d\n' 1000
    1
   42
 1000

%5d means "use a field at least 5 characters wide, right-aligned." Numbers of different lengths line up on the right edge.

Keep these common combinations in mind.

Form Meaning Example output
%5d Width 5, right-aligned ␣␣␣42
%-5d Width 5, left-aligned 42␣␣␣
%05d Width 5, zero-padded 00042
%.2f 2 decimal places 3.14
%8.2f Width 8, 2 decimals, right ␣␣␣␣3.14
%-10s Width 10, left-aligned string abc␣␣␣␣␣␣␣

( represents a space.)

Lina: The - in %-10s means left-align! That looks perfect for lining up labels in a table.
Linny-senpai: Exactly the right use. Left-align the item names and right-align the prices, and it lines up like a receipt.
printf '%-10s %5d USD\n' apple 100
printf '%-10s %5d USD\n' banana 80
printf '%-10s %5d USD\n' melon 1200
apple        100 USD
banana        80 USD
melon       1200 USD

Width is counted in characters, so full-width characters (like CJK text) may not line up perfectly. Plain ASCII letters and numbers align cleanly.

5. What Escape Sequences Are Common?

Conclusion: \n is a newline, \t is a tab, and \\ is a literal backslash. They have special meaning inside the format string.

Lina: \n was a newline, right? Are there others?
Linny-senpai: The tab \t is used a lot -- it separates columns to look like a table. Here are the common ones.
Form Meaning
\n Newline
\t Tab
\\ A literal backslash \
\r Carriage return (line start)
printf 'Name\tAge\n'
printf 'Lina\t17\n'
Name	Age
Lina	17

To print a backslash itself, write \\ (two of them). A single \n is read as "make a newline" instead.

6. What Happens When There Are Fewer Specifiers Than Values?

Conclusion: When values outnumber specifiers, printf reuses the format from the start. This lets you print a list in one line.

Lina: If I write printf '%s\n' a b c with one %s but three values, does it error?
Linny-senpai: No. When values are left over, printf reuses the format string from the beginning. So they print on three separate lines.
printf '%s\n' apple banana melon
apple
banana
melon

Because %s\n repeats for each value, all three print with their own newline. This is the go-to trick for stacking a list neatly.

The reverse also holds: missing values are treated as an empty string or 0. For example, printf '%s and %s\n' apple prints "apple and (empty)".

7. What Are the Common Pitfalls?

Conclusion: The classics are forgetting the newline, forgetting to double %, and mismatching the value type with the specifier. Slow down and recheck the format string.

Lina: I feel like I could write this myself now! But I'm afraid of messing up...
Linny-senpai: Don't worry. The pitfalls are predictable, so knowing them in advance takes away the fear.

Pitfall 1: Forgetting the newline

printf '%s' penguin does not add a newline, so the next prompt sticks to it. Add \n at the end.

Pitfall 2: Writing % literally

printf '50% done\n' misreads %␣ as a specifier. To print a literal %, double it: printf '50%% done\n'.

Pitfall 3: Type and specifier mismatch

Passing a string to %d, or a number where you meant %s. This causes nothing to print, a 0, or a warning.

Mini exercise (click for the answer)

Write a printf that left-aligns an item name in width 8, right-aligns the price in width 6, and ends with "USD" and a newline.

One possible answer:

printf '%-8s %6d USD\n' coffee 350
coffee      350 USD

Next Reading