Skip to content

Функция printf в bash

printf (print formatted, функция форматированного вывода) - встроенная функция bash; есть и бинарник, обычно, в дистрибутивах, но он будет работать только, если указать вызвать его конкретно (/usr/bin/env или env printf).
Определена в стандарте POSIX (в отличие от (тоже) встроенной в bash функции echo), поэтому лучше переносима с POSIX-совместимыми системами.

printf, в отличие от echo, не добавляет по дефолту перевод строки.

Bash
printf '%s\n' 'Some \n text'
# Some \n text

# %b включает интерпретацию управляющих последовательностей
printf '%b\n' 'Some \n text'
# Some 
#  text

Управляющие последовательности (\n и т.п.) будут интерпретироваться и в одинарных, и в двойных кавычках.

Дата/время в printf

В bash 4.2 добавили поддержку спецификатора формата printf %(date_format)T, которая по дефолту выводила дату начала эпохи Unix (1970-01-01 00:00:00 -0000).
В bash 4.3 дефолтное значение стало полезней - выводились текущие дата и время. Спецификатор имеет два спец. аргумента: "-1" - текущие дата и время, "-2" - дата и время вызова оболочки.

С помощью printf -v var можно сохранить вывод в переменную var вместо вывода на экран (подобно функции sprintf в C):

Bash
printf -v today '%(%F)T' '-1'
echo "$today"
# 2023-10-13

printf можно юзать для простого логирования:

Bash
# оба варианта выводят одно и тоже
printf '%(%F %T %z)T: %s\n' '-1' 'Some log msg'
printf '%(%Y-%m-%d %H:%M:%S %z)T: %s\n' '-1' 'Some log msg'
# 2023-10-13 20:19:28 +0300: Some log msg

Команда date в этом плане лучше, чем printf %(date_format)T, ибо позволяет выполнять арифметические действия с датами, например:

Bash
date -d '2 months ago' '+%B'  # название позапрошлого месяца
August

Но printf %(date_format)T дает возможность не создавать подоболочку для запуска date. Это удобно, если нужно просто зафиксировать время (например, при логировании).

С помощью него можно узнать, например, какой дате и времени соответствуют 1072632362 секунд:

Bash
printf '%(%F %T)T = %s\n' '1072632362' '1072632362s to human readable'
# 2003-12-28 20:26:02 = 1072632362s to human readable

printf для повторного использования или отладки

\%q экранирует символы в аргументе, позволяя юзать его повторно в качестве ввода.

Bash
printf '%q' "This example is from $today\n"
# This\ example\ is\ from\ 2023-10-13\\n

Такое может пригодится для повторного использования в другом месте, создания форматированного вывода и отладки, когда нужно видеть скрытые управляющие символы и поля.


Соус: Книга "Идиомы Bash" --> Глава 6. "Функции" --> "Функция printf"

bash