AWK Output

Chapter 5
printf and Formatted Output
Going beyond plain print when output needs to be aligned, padded, or precisely formatted

Every example so far has used print, which is simple but offers no control over spacing or formatting — fields just get separated by OFS and that's it. printf gives full control: column alignment, fixed decimal places, padded numbers — genuinely useful the moment output needs to look like a readable table rather than just raw values.

The Basic Syntax

$ awk '{ printf "%s is %d years old\n", $1, $2 }' people.txt

A format string with placeholders (%s, %d, etc.), followed by a comma-separated list of values to fill those placeholders, in order. Unlike print, printf does not add a newline automatically — the \n has to be written explicitly, every time.

Forgetting \n is the single most common printf mistake
Without it, every line of output runs together with no break at all — a wall of concatenated text instead of one line per record. print spoiled this expectation by adding a newline for you automatically; printf never does.

Format Specifiers

SpecifierFormats as
%sString, as-is
%dInteger (decimal)
%fFloating-point number, default 6 decimal places
%.2fFloating-point, exactly 2 decimal places — for currency, percentages
%5dInteger, right-padded to a minimum width of 5 characters
%-10sString, LEFT-aligned, padded to a minimum width of 10 characters
%%A literal percent sign — needed because % alone starts a specifier

Building an Aligned Table

This is where printf genuinely earns its place over plain print — turning ragged, inconsistently-spaced output into a clean, column-aligned table.

$ awk '{ printf "%-10s %5d %8.2f\n", $1, $2, $3 }' sales.txt
philip 42 199.50 admin 7 49.99 guest 156 1024.00

%-10s left-aligns the name within 10 characters; %5d right-aligns the integer within 5; %8.2f right-aligns the decimal within 8 characters, always showing exactly 2 decimal places — regardless of how differently-sized the original values were.

A header row with the same widths makes a genuinely readable report
Adding a BEGIN block (Chapter 3) with a matching printf for column headers, using the same width specifiers, produces output that looks like a real formatted table rather than a raw data dump — a small addition that makes scripted reports far more usable.
$ awk '
BEGIN { printf "%-10s %5s %8s\n", "NAME", "AGE", "TOTAL" }
{ printf "%-10s %5d %8.2f\n", $1, $2, $3 }
' sales.txt
NAME AGE TOTAL philip 42 199.50 admin 7 49.99 guest 156 1024.00

printf Inside sprintf — Building Strings Without Printing

sprintf behaves identically to printf but returns the formatted result as a string instead of printing it — useful when the formatted text needs to be used in further processing rather than output immediately.

$ awk '{ label = sprintf("%-10s (%d)", $1, $2); print label }' file.txt

Chapter 5 Quick Reference

  • printf "format", values — no automatic newline, unlike print; \n must be explicit
  • %s, %d, %f — string, integer, floating-point; %.2f — fixed decimal places
  • %5d — right-aligned, min width 5; %-10s — left-aligned, min width 10
  • %% — a literal percent sign
  • Combine width specifiers across fields to build genuinely aligned table output
  • sprintf — same formatting, returns a string instead of printing it
  • Next chapter: arrays in AWK — associative arrays, counting, grouping