printf
The printf command behaves similarly to the C printf() function and gives you more control over formatting
Print a sequence of numbers
for i in $(seq 0 99); do printf '%s\n' "$i"; done
Print alphabet in order
i=97; while [ $i -le 122 ]; do printf '%b\n' "\\$(printf '%03o' "$i")"; i=$((i+1)); done
Print a horizontal line (minimal ash where tput is not installed)
printf '%*s\n' "${COLUMNS:-80}" '' | tr ' ' "${1-_}"
Print a horizontal line (bash)
printf -v _hr "%*s" $(tput cols) && echo ${_hr// /${1--}}
Print a horizontal line (ash)
w=${COLUMNS:-80}; i=0; while [ $i -lt "$w" ]; do printf '%s' "${1--}"; i=$((i+1)); done; printf '\n'
Print date with colorized Date
printf "\033[33mDate:\033[37m %s\033[0m\n" "$(date)"
Print a random uuid
printf '%08x-%04x-%04x-%04x-%012x\n' $RANDOM$RANDOM $RANDOM $RANDOM $RANDOM $RANDOM$RANDOM$RANDOM
Print a random uuid in ash shell
hexdump -n16 -e '4/4 "%08x" 1 "\n"' /dev/urandom | sed 's/\(........\)\(....\)\(....\)\(....\)\(............\)/\1-\2-\3-\4-\5/'
Repeat printing string 5 times
printf 'hello world\n%.0s' {1..5}
Display each directory in $PATH on a separate sine
printf ${PATH//:/\\n}
List all files in every directory defined in $PATH
printf "%s\n" ${PATH//:/\/* }
Enumerate all executable files in $PATH with Absolute Paths
(IFS=:; for d in $PATH; do for f in "$d"/*; do [ -f "$f" ] && [ -x "$f" ] && printf '%s\n' "$f"; done done) | sort -u
Enumerate all executable filenames available in $PATH
(IFS=:; for d in $PATH; do for f in "$d"/*; do [ -f "$f" ] && [ -x "$f" ] && printf '%s\n' "${f##*/}"; done; done) | sort -u
Zero-pad integers to 4 digits
printf '%04d\n' 1 23 456
Left and right align text in columns
printf '%-10s %10s\n' "USER" "SHELL"
Print floating point numbers with precision
printf '%.3f\n' 3.1415926535
Print table headers with dynamic width
printf '%-15s %-10s %-5s\n' "Username" "Shell" "UID"
Convert decimal to hexadecimal
printf '0x%X\n' 255
Convert decimal to octal
printf '0%o\n' 755
Print binary representation (bash arithmetic)
printf '%08d\n' "$(echo "obase=2; 13" | bc)"
Escape special characters safely
printf '%q\n' 'hello world & $(rm -rf ~/somefile)'
Command substitution inside double quotes is executed BEFORE printf runs
printf '%s\n' "$(echo injected)"
Print NUL-terminated strings (for xargs -0)
printf '%s\0' file1 file2 file3
Generate a progress bar
p=30; w=50; printf '[%-*s] %d%%\n' "$w" "$(printf '%*s' $((p*w/100)) | tr ' ' '#')" "$p"
Print colored success and error messages
printf '\033[32m[OK]\033[0m Operation completed\n'
Timestamped log entry
printf '[%(%F %T)T] %s\n' -1 "Service started"
Print environment variables in key=value format
printf '%s=%q\n' USER "$USER"
Create formatted CSV output
printf '"%s","%s","%s"\n' "alice" "1000" "/bin/bash"
PAdding characters in printf
line='----------------------------------------'
PROC_NAME='abc'
printf "%s %s [UP]\n" $PROC_NAME "${line:${#PROC_NAME}}"
PROC_NAME='abcdef'
printf "%s %s [UP]\n" $PROC_NAME "${line:${#PROC_NAME}}"
Padding characters at same length when using ping
list=(localhost google.com linux-shell.se idg.se thiswillfail)
C=1
for M in "${list[@]}"
do
machine_indented=$(printf '%-20s' "$M")
machine_indented=${machine_indented// /.}
if ping -q -c 1 "$M" &>/dev/null ; then
printf "(%2d) %s CONNECTION \e[1;32mOK\e[0m\n" "$C" "$machine_indented"
else
printf "(%2d) %s CONNECTION \e[1;31mFAIL\e[0m\n" "$C" "$machine_indented"
fi
((C=C+1))
done
Make a rectangle box that fits 3 lines vertical and a full horizontal line over entire screen
cols=$(stty size 2>/dev/null | cut -d' ' -f2 || echo 80)
# Topp
printf "+%$(($cols-2))s+\n" | tr " " "-"
# Sidor
for i in {1..3}; do
printf "|%$(($cols-2))s|\n" " "
done
# Botten
printf "+%$(($cols-2))s+\n" | tr " " "-"
Print a vertical line
for i in $(seq 1 10); do
printf "|\n"
done
v_line() {
while IFS= read -r line; do
printf "| %s\n" "$line"
done
}
df -h | v_line
for i in $(seq 1 10); do
printf "\033[%d;20H|" "$i"
done
echo -e "\033[11;1H"
rows=$(stty size 2>/dev/null | cut -d' ' -f1 || echo 24)
for ((i=1; i<=rows; i++)); do
printf "|\n"
done
v_line() {
local color="\033[1;32m" # Grön färg för linjen (valfritt)
local reset="\033[0m"
while IFS= read -r line; do
printf "${color}|${reset} %s\n" "$line"
done
}
df -h | v_line
rows=$(stty size 2>/dev/null | cut -d' ' -f1 || echo 24)
for i in $(seq 1 $rows); do
# \033[rad;kolumnH flyttar markören
printf "\033[%d;10H|" "$i"
done
printf "\033[%d;1H" "$rows"
Print a horizontal line over entire screen
rintf -v _hr "%*s" $(tput cols) && echo ${_hr// /${1--}}
printf '%*s' "$(tput cols)" '' | tr ' ' "${1--}"
for ((i=0; i<COLUMNS; i++)); do printf "${1--}"; done; echo
printf "%$(stty size | cut -d' ' -f2)s" " " | tr " " "${1--}"
printf "%$(stty size | cut -d' ' -f2)s" " " | tr " " "${1--}"
cols=$(stty size 2>/dev/null | awk '{print $2}')
: ${cols:=80} # Om stty failar, sätt till 80
for i in $(seq 1 $cols); do printf "${1--}"; done; echo
cols=${COLUMNS:-80}
printf "%${cols}s" " " | tr " " "${1--}"
hr() {
local c=${1--}
local cols
cols=$(stty size 2>/dev/null | cut -d' ' -f2)
[ -z "$cols" ] && cols=${COLUMNS:-80}
# Skapa linjen effektivt utan externa binärer
local line
printf -v line "%*s" "$cols" ""
echo "${line// /$c}"
}