zaLinux.ru

Инструкция по использованию printf в Bash для форматирования и вывода данных


В отличие от многих других команд, команда 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.


Рекомендуемые статьи:

2 Комментарии

  1. Влад

    Здравствуйте!

    Как вывести число как есть? Пример:

    printf 'Значение: %s' 2022 2023

    выводит как

    Значение: 2022Значение: 2023

    а нужно как

    Значение: 2022 2023

    Само значение "2022 2023" получается в результате работы другой команды. Похоже что пробел является каким-то разделителем, где он задаётся?

    1. Alexey (Автор записи)

      Приветствую! Прежде всего, возможно, вам и не нужен printf, если вы хотите просто вывести значение команды, предварив его заданной строкой:

      echo 'Значение: '`echo {2022..2023}`

      Пробел является специальным символом для самой оболочки, а не только для printf. Для того, чтобы пробел перестал иметь специальное значение и трактовался как обычный символ, выражение с пробелом нужно поместить в одинарные или двойные кавычки, например:

      printf 'Значение: %s' '2022 2023'

      Как вариант, любой специальный символ можно экранировать:

      printf 'Значение: %s' 2022\ 2023

      Пример использования printf, когда аргумент генерируется другой командой и содержит пробел:

      printf 'Значение: %s' "`echo {2022..2023}`"
      

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *