Skip to content

Instantly share code, notes, and snippets.

@supersym
Last active December 11, 2015 01:08
Show Gist options
  • Save supersym/4520950 to your computer and use it in GitHub Desktop.
Save supersym/4520950 to your computer and use it in GitHub Desktop.

printf <ARGUMENTS...>

Format and print data. Write the formatted arguments to the standard output under the control of the format.

The built-in printf (print formatted) command prints a message to the screen. You will use this command a lot in shell scripts.

Use-case example 1

Include a format code for each item you want to print. Each format code is replaced with the appropriate value when printed. Any characters in the format string that are not part of a formatting instruction are treated as printable characters.

printf "There are %d customers with purchases over %d.\n" 50 20000

Use-case example 2

printf is sometimes used to redirect a variable or some unchanging input to a command. For example, suppose all you want to do is pipe a variable to a command. Instead of using printf, Bash provides a shortcut <<< redirection operator. <<< redirects a string into a command as if it were piped using printf.

The tr command can convert text to uppercase. This example shows an error message being converted to uppercase with both printf and <<<.

printf "%s\n" "$ERRMSG" | tr [:lower:] [:upper:]
WARNING: THE FILES FROM THE OHIO OFFICE HAVEN'T ARRIVED.
tr [:lower:] [:upper:] <<< "$ERRMSG"
WARNING: THE FILES FROM THE OHIO OFFICE HAVEN'T ARRIVED.

Alignment / justification

To create reports with neat columns, numbers can proceed many of the formatting codes to indicate the width of a column. For example, "%10d" prints a signed number in a column 10 characters wide.

printf "%10d\n" 11
# 11

Likewise, a negative number left-justifies the columns.

printf "%-10d %-10d\n" 11 12
# 11     12

A number with a decimal point represents a column width and a minimum number of digits (or decimal places with floating-point values). For example, "%10.5f" indicates a floating-point number in a 10-character column with a minimum of five decimal places.

printf "%10.5f\n" 17.2
# 17.20000

Formatting

Finally, an apostrophe ' displays the number with thousands groupings based on the current country locale.

The \n in the format string is an example of a backslash code for representing unprintable characters. \n indicates a new line should be started. There are special backslash formatting codes for the representation of unprintable characters.

  • \b—Backspace
  • \f—Form feed (that is, eject a page on a printer)
  • \n—Start a new line
  • \r—Carriage return
  • \t—Tab
  • \v—Vertical tab
  • '—Single quote character (for compatibility with C)
  • \—Backslash
  • \0n—n is an octal number representing an 8-bit ASCII character
printf "Two separate\nlines\n"
# Two separate
# lines

Character encoding

Any 8-bit byte or ASCII character can be represented by \0 or \ and its octal value.

printf "ASCII 65 (octal 101) is the character \0101\n"
# ASCII 65 (octal 101) is the character A

printf recognizes numbers beginning with a zero as octal notation, and numbers beginning with 0x as hexadecimal notation. As a result, printf can convert numbers between these different notations.

printf "%d\n" 010
# 8
printf "%d\n " 0xF
# 15
printf "0x%X\n " 15
# 0xF
printf "0%o\n " 8
# 010

Most Linux distributions also have a separate printf command to be compliant with the POSIX standard.

Huge list of (almost) one-liners

# Print the decimal representation of a hexadecimal number (preserve the sign)
  printf "%d\n" 0x41
  printf "%d\n" -0x41
  printf "%+d\n" 0x41
# Print the octal representation of a decimal number
  printf "%o\n" 65
  printf "%05o\n" 65 (5 characters width, padded with zeros)
# This prints a 0, since no argument is specified
  printf "%d\n"
# Print the code number of the character A
  printf "%d\n" \'A
  printf "%d\n" "'A"
# Generate a greeting banner and assign it to the variable GREETER
  printf -v GREETER "Hello %s" "$LOGNAME"
# Print a text at the end of the line, using tput to get the current line width
  printf "%*s\n" $(tput cols) "Hello world!"
# Loop and print all numbers from 0 to 127 in decimal, octal, hex
  for ((x=0; x <= 127; x++)); do printf '%3d | %04o | 0x%02x\n' "$x" "$x" "$x";  done
# Take a common MAC address and rewrite it into a well-known format 
  the_mac="0:13:ce:7:7a:ad"
# Lowercase hex digits
  the_mac="$(printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${the_mac//:/ 0x})"
# Or the uppercase-digits variant
  the_mac="$(printf "%02X:%02X:%02X:%02X:%02X:%02X" 0x${the_mac//:/ 0x})"
# Working off the replacement echo, here is a terse implementation of prargs:
  printf '"%b"\n' "$0" "$@" | nl -v0 -s": "
# A small trick: Combining printf and parameter expansion to draw a line
  length=40; printf -v line '%*s' "$length"; echo ${line// /-}
# Alternative to the above to draw a line
  length=40; eval printf -v line '%.0s-' {1..$length}
# The %(…)T format string is a direct interface to strftime(3).
  printf 'This is week %(%U/%Y)T.\n' -1
# Using printf inside of awk the proper way awk likes you to
  echo "Foo" | awk '{ printf $1 "\n" }'
# Format a number:
  for ((i=1; i<=10; i++)); do printf "%02d " "$i"; done
# Command printf will implicitly loop if given more arguments than format specifiers: refactor!
  printf "%03d\n" {1..300}
# If you don't know in advance what the starting and ending values are (but integers):
  eval printf '"%03d\n"' {$start..$end}
# Works w. any Bourne derived shell (which has expr and sed) to zero-pad each line to three bytes: 
  i=0; while test $i -le 10; do echo "00$i"; i=`expr $i + 1`; done |sed 's/.*\(...\)$/\1/g'
# But you might as well just do the whole thing in awk: count variable contains an integer
  awk -v count="$count" 'BEGIN {for (i=1;i<=count;i++) {printf("%03d\n",i)} }'
# Bourne, with Solaris's decrepit and useless awk:
  awk "BEGIN {for (i=1;i<=$count;i++) {printf(\"%03d\\n\",i)} }"
# Number one reason this question is asked, is for downloading images in bulk with `xargs` & `wget`
  almost any example above | xargs -i% wget $LOCATION/%
# B3 Read a line of input using a for loop  and replace the % at the end of the command with the input.
  for i in {1..100}; do wget "$prefix$(printf %03d $i).jpg"; sleep 5; done
# B3.1 Avoiding the subshells
  for i in {1..100}; do printf -v n %03d $i; wget "$prefix$n.jpg"; sleep 5; done
# Format operand used 3 times to print all given strings, '0' was supplied to satisfy the last %4d
  printf "%5d%4d\n" 1 21 321 4321 54321
# Using ANSI colors
  printf '\e[1;34m%-6s\e[m' "This is text"
# Colorized and outlined by tput
  blue=$(tput setaf 4)
  normal=$(tput sgr0)
  printf "%40s\n" "${blue}This text is blue${normal}"
# Formatting prints a zero-padded (the 0 after %) two-character long number for directory name
  for ((x=1;x< =31;x+=1)); do mkdir `printf "%02d" $x`; done
# Generate the alphabet from a-z without spaces between characters
  printf "%c" {a..z}
# Same but with newline
  printf "%c" {a..z} $'\n'
# Or in column
  printf "%c\n" {a..z}
# Puts the 'abcd...' in the $alphabet variable
  printf -v alphabet "%c" {a..z}
# Pad numbers 0 to 9 with a leading zero
  printf "%02d " {0..9}
# Generate 30 english words 
  printf "%s\n" {w,t,}h{e{n{,ce{,forth}},re{,in,fore,with{,al}}},ither,at}
# To printf floating point numbers a %f specifier is our friend:
  printf "%f\n" 255 0xff 0377 3.5
# Consider the following data structure: hiddenhausen,99.60,y - clean awk columns
  awk '{ printf "%-15s%-8s%s\n",$1,$2,$3}' FS=\, file.txt
# Redirect stderr to stdout to a file
  printf "%s\n%\n" Hello world > FILE 2>&1
# The order of the above redirections matters:
  printf "%s\n%\n" Hello world 2>&1 > FILE
# Non-standard method of redirecting both interfaces
  printf "%s\n%\n" Hello world &> FILE

  

References

http://linuxconfig.org/bash-printf-syntax-basics-with-examples http://www.linuxcommand.org/wss0140.php http://wiki.bash-hackers.org/commands/builtin/printf http://jonathanwagner.net/2007/04/zero-padding-in-bash/ http://www.informit.com/articles/article.aspx?p=169504&seqNum=2 http://ruslanspivak.com/2012/04/16/bash-nonstandard-redirection/ http://unstableme.blogspot.nl/2009/07/text-alignment-with-awk-printf-function.html http://www.catonmat.net/blog/bash-one-liners-explained-part-two/ http://martin-thoma.com/colorize-your-scripts-output/ http://stackoverflow.com/questions/5412761/using-colors-with-printf http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html http://mywiki.wooledge.org/BashFAQ/018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment