В отличие от многих других команд, команда printf не используется для конвейеров (она не принимает стандартный ввод) и не находит частого применения непосредственно в командной строке (чаще всего используется в сценариях). Так почему так важна? Потому что printf так широко используется.
printf (от фразы «print formatted») изначально был разработан для языка программирования C и был реализован во многих языках программирования, включая оболочку. Фактически, в bash printf является встроенной командой.
printf работает так:
printf "ФОРМАТ" АРГУМЕНТЫ
Команде даётся строка, содержащая описание формата, которое затем применяется к списку аргументов. Отформатированный результат отправляется на стандартный вывод. Вот банальный пример:
printf "Я отформатировал строку: %s\n" аргумент Я отформатировал строку: аргумент
Строка формата может содержать буквальный текст (например, «Я отформатировал строку:»), escape-последовательности (например, \n, символ новой строки) и последовательности, начинающиеся с символа %, которые называются спецификациями преобразования. В приведённом выше примере спецификация преобразования %s используется для форматирования строки «аргумент» и помещения её в выходные данные команды. И снова:
printf "Я отформатировал '%s' как строку.\n" аргумент Я отформатировал 'аргумент' как строку.
Как мы видим, спецификация преобразования %s заменена строкой «аргумент» в выводе команды. Преобразование s используется для форматирования строковых данных. Есть и другие спецификаторы для других видов данных. В этой таблице перечислены наиболее часто используемые типы данных:
Общие спецификаторы типов данных printf
Спецификатор | Описание |
---|---|
d | Форматировать число как десятичное целое со знаком. |
f | Форматировать и вывести число с плавающей запятой. |
o | Форматировать целое число как восьмеричное число. |
s | Форматировать строку. |
x | Форматировать целое число как шестнадцатеричное, используя строчные буквы a-f, где необходимо. |
X | То же, что и x, но с прописными буквами. |
e | Научная нотация (экспоненциальная запись) в форме [-]d.ddde±dd, например, 1,233300e+04 |
E | То же, что и e, но с прописной буквой E, например, 1,233300E+04. |
% | Вывести буквальный символ (т.е. укажите «%%») |
Мы продемонстрируем влияние каждого из спецификаторов преобразования на строку «380»:
printf "%d, %f, %o, %s, %x, %X\n" 380 380 380 380 380 380 380, 380,000000, 574, 380, 17c, 17C
Поскольку мы указали шесть спецификаторов преобразования, мы также должны предоставить шесть аргументов для обработки printf. Шесть результатов показывают влияние каждого спецификатора.
К спецификатору преобразования можно добавить несколько дополнительных компонентов, чтобы настроить его вывод. Полная спецификация преобразования может состоять из следующего:
%[флаги][ширина][.точность]спецификация_конвертации
При использовании нескольких необязательных компонентов они должны появляться в указанном выше порядке, чтобы их можно было правильно интерпретировать. Вот описание каждого из них:
Компоненты спецификации преобразования printf
Компонент | Описание |
---|---|
флаги |
Есть пять разных флагов: # – использовать «альтернативный формат» для вывода. Это зависит от типа данных. Для преобразования o (восьмеричное число) вывод имеет префикс 0. Для преобразований x и X (шестнадцатеричное число) выводом является префиксы с 0x или 0X соответственно. 0 – (ноль) означает заполнит вывод нулями. Это означает, что поле будет заполняться ведущими нулями, как в «000380». - – (тире) означает выровнять вывод по левому краю. По умолчанию printf выравнивает выход по правому краю. ‘ ’ – (пробел) создаёт начальный пробел для положительных чисел. + – (знак плюса) добавит знак к положительным числам. По умолчанию printf пишет знак только для отрицательных исел. |
ширина | Число, указывающее минимальную ширину поля. |
.точность | Для чисел с плавающей запятой укажет количество цифр точности, выводимых после десятичной точки. Для преобразования строк точность определяет количество выводимых символов. |
Вот несколько примеров использования различных форматов:
Примеры спецификации преобразования printf
Аргумент | Формат | Результат | Примечание |
---|---|---|---|
380 | "%d" | 380 | Простое форматирование целого числа. |
380 | "%#x" | 0x17c | Целое число, отформатированное как шестнадцатеричное число с использованием флага «альтернативного формата». |
380 | "%05d" | 00380 | Целое число с начальными нулями (заполнение) и минимальной шириной поля в пять символов. |
380 | "%05.5f" | 380.00000 | Число в формате числа с плавающей запятой с заполнением и точностью до пяти десятичных знаков. Поскольку указанная минимальная ширина поля (5) меньше фактической ширины отформатированного числа, заполнение не действует. |
380 | "%010.5f" | 0380.00000 | При увеличении минимальной ширины поля до 10 теперь видны отступы. |
380 | "%+d" | +380 | Флаг + обозначает добавить знак к положительному числу. |
380 | "%-d" | 380 | Флаг - означает левое выравнивание форматирования. |
abcdefghijk | "%5s" | abcedfghijk | Строка, отформатированная с минимальной шириной поля. |
abcdefghijk | "%.5s" | abcde | Применяя точность к строке, она усекается. |
Опять же, printf используется в основном в сценариях, где он используется для форматирования табличных данных, а не непосредственно в командной строке. Но мы все ещё можем показать, как его можно использовать для решения различных проблем форматирования. Сначала давайте выведем несколько полей, разделённых символами табуляции:
printf "%s\t%s\t%s\n" str1 str2 str3 str1 str2 str3
Вставив \t (escape-последовательность для табуляции), мы достигаем желаемого эффекта. Далее несколько чисел с аккуратным форматированием:
printf "Строка: %05d %15.3f Результат: %+15d\n" 1071 3,14156295 32589 Строка: 01071 3,142 Результат: +32589
Это показывает влияние минимальной ширины поля на расстояние между полями.
А как насчёт форматирования крошечной веб-страницы:
printf "<html>\n\t<head>\n\t\t<title>%s</title>\n\t</head>\n\t<body>\n\t\t<p>%s</p>\n\t</body>\n</html>\n" "Заголовок страницы" "Содержимое страницы" Вывод: <html> <head> <title>Заголовок страницы</title> </head> <body> <p>Содержимое страницы</p> </body> </html>
Ошибка «bash: printf: …: недопустимое число»
Если при использовании printf вы столкнулись с ошибкой «недопустимое число», например:
bash: printf: 3.14156295: недопустимое число
Если вы действительно указали правильное число, но получаете эту ошибку, то дело может быть в десятичной точке, а именно в используемом для неё символе.
Суть в том, что в разных странах в качестве десятичной точки используется либо точка, либо запятая. В компьютере принимаемый в качестве десятичной точки символ зависит от локали ОС. Если вы получили указанную ошибку, то просто попробуйте заменить точку в числе на запятую (или наоборот, запятую на точку), например, вместо числа 3.14156295 используйте чисто 3,14156295.
Связанные статьи:
- Как добавить нули до определённого размера строки (71%)
- Как удалить newline (символ новой строки) из вывода команд и файлов в командной строке Linux (64.5%)
- Как отфильтровать текст, находящийся между двумя определёнными строками (56.5%)
- Как добавить строку в начало или в конец каждой строчки (56.5%)
- Как сделать замену от совпадения до конца строки (56.5%)
- Уроки по Awk (RANDOM - 50%)
Здравствуйте!
Как вывести число как есть? Пример:
выводит как
а нужно как
Само значение "2022 2023" получается в результате работы другой команды. Похоже что пробел является каким-то разделителем, где он задаётся?
Приветствую! Прежде всего, возможно, вам и не нужен printf, если вы хотите просто вывести значение команды, предварив его заданной строкой:
Пробел является специальным символом для самой оболочки, а не только для printf. Для того, чтобы пробел перестал иметь специальное значение и трактовался как обычный символ, выражение с пробелом нужно поместить в одинарные или двойные кавычки, например:
Как вариант, любой специальный символ можно экранировать:
Пример использования printf, когда аргумент генерируется другой командой и содержит пробел: