Printf
Printf как замена команды echo
Эта команда была создана для замены всем знакомой команды echo. Возможности команды echo ограничены, кроме того, в разных ветках Unix'а оказались разные ее версии, что приводит к несовместимости. Поэтому Posix рекомендует пользоваться командой printf. Команда printf выводит АРГУМЕНТ на стандартный вывод (как правило, экран дисплея), используя при этом определенный ФОРМАТ.
$ printf 'ФОРМАТ' 'АРГУМЕНТ'
Эта команда была создана для замены всем знакомой команды echo (настолько древней, что даже имя ее автора не известно).
Самое первое, что следует прояснить: по умолчанию команда printf не переводит строку по завершении. Это выглядит так:
[ya@antony ~]$ printf '%s' 'alex' alex[ya@antony ~]$
Следующее приглашение командной строки находится на той же самой строке что и вывод предыдущей команды. Это очень неудобно, поэтому в ФОРМАТ приходится добавлять символ новой строки (\n):
[ya@antony ~]$ printf '%s\n' 'alex' alex [ya@antony ~]$
Приглашение переехало на новую строку, и все обрело привычный вид. В дальнейшем я не стану приводить приглашение целиком, ограничусь знаком доллара.
Вот как выглядит команда printf в виде, полностью дублирующем команду echo:
$ printf '%b\n' 'Это заклинание заменит команду echo' Это заклинание заменит команду echo
Обратите внимание, что мы взяли аргумент в кавычки, чтобы получить его в виде одной строки. Если бы мы этого не сделали, то имели бы столбик, так как программа воспринимает выражения, разделенные пробелом, как множественные аргументы, и обрабатывает каждый в соответствии с заданным форматом:
$ printf '%b\n' Это заклинание заменит команду echo Это заклинание заменит команду echo
Если нам нужно использовать команду printf для просмотра переменных окружения, то кавычки не нужны:
$ printf '%b\n' $PATH /home/ya/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin:/usr/games:/usr/X11R6/bin
Если же мы возьмем аргумент в кавычки, то он будет воспринят просто как выражение и воспроизведен дословно:
$ printf '%b\n' '$PATH' $PATH
Но довольно о замене команды echo, займемся непосредственно командой printf.
Описание и использование
Представление аргумента
N Нормальное десятичное число. Например 177
0N Восьмеричное число. Например 024.
0xN и 0XN Шестнадцатеричные числа. Например 0?41.
"А (обычные кавычки перед любой буквой) Интерпретируется как кодовый номер этой буквы в текущей кодировке. С кириллицей не работает.
'А (одинарные кавычки перед любой буквой) Интерпретируется как кодовый номер этой буквы в текущей кодировке. С кириллицей не работает.
Форматы команды printf
Вообще говоря, синтаксис команды printf взят от функции printf() языка программирования Си (и еще дюжины других). Но далеко не все знакомы с Си, поэтому мы внимательно рассмотрим все тонкости синтаксиса этой команды.
ФОРМАТ пишется в командной строке непосредственно после самой команды и заключается в кавычки - двойные или одинарные. Собственно говоря, кавычки нужны не всегда, но лучше их ставить, во избежание недоразумений. Это полезная привычка. (А ведь большинство привычек - вредные).
%b Рассматривает аргумент как строку, при этом интерпретирует все управляющие символы, содержащиеся в ней.
%s Рассматривает аргумент как просто как строку.
%c Рассматривает аргумент как символ, при этом берется первый символ выражения или строки.
%q Преобразует строку к виду, пригодному к использованию в качестве ввода в шелл.
Здесь необходимы пояснения. Допустим, мы хотим напечатать на экране фразу:
Ваш, Алексей Дмитриев
Для этого дадим следующую команду:
$ printf '%b\n' 'Ваш,\nАлексей Дмитриев' Ваш, Алексей Дмитриев
А теперь вместо формата %b применим формат %q:
$ printf '%q\n' 'Ваш,\nАлексей Дмитриев' $'\320\222\320\260\321\210,\\n\320\220\320\273\320\265\320\272\321\201\320\265\320\271 \320\224\320\274\320\270\321\202\321\200\320\270\320\265\320\262'
Кажется, произошла какая-то ошибка или сбой. Но это не так; подставим вывод команды в качестве аргумента команды printf '%b\n', но уже безо всяких дополнительных кавычек (все необходимые кавычки содержатся в выводе команды):
$ printf '%b\n' $'\320\222\320\260\321\210,\\n\320\220\320\273\320\265\320\272\321\201\320\265\320\271 \320\224\320\274\320\270\321\202\321\200\320\270\320\265\320\262' Ваш, Алексей Дмитриев
Больше того, этот же вывод можно использовать в качестве аргумента для других команд, скажем echo -e (опция -e позволяет команде echo интерпретировать специальные символы, в частности символ новой строки (\n):
$ echo -e $'\320\222\320\260\321\210, \\n\320\220\320\273\320\265\320\272\321\201\320\265\320\271 \320\224\320\274\320\270\321\202\321\200\320\270\320\265\320\262' Ваш, Алексей Дмитриев
Вот какой интересный формат %q! Однако продолжим.
Дальше идут всевозможные форматы представления чисел.
%d Представляет аргумент в виде десятичного числа, могущего иметь знак (+ или -).
%u Представляет аргумент в виде десятичного числа, не имеющего знака.
$ printf '%d\n' -777 -777
%i То же, что и предыдущее.
%o Представляет аргумент в виде не имеющего знака восьмеричного числа.
$ printf '%o\n' 777 1411
%x Представляет аргумент в виде не имеющего знака шестнадцатеричного числа. Буквы пишутся в нижнем регистре.
$ printf '%x\n' 177 b1
%X Представляет аргумент в виде не имеющего знака шестнадцатеричного числа, при этом буквы пишутся в верхнем регистре.
$ printf '%X\n' 177 B1
%f Интерпретирует аргумент как число с плавающей запятой.
$ printf '%f\n' 17,7 17,700000
%e Интерпретирует аргумент с удвоенной точностью (double precision), при этом выводит его в формате <N>+/-e<N>.
$ printf '%e\n' 177 1,770000e+02
%E То же, что и предыдущее, только с заглавной буквой Е.
Вот и все форматы, я привел их для встроенной в bash команды printf.
Модификаторы форматов
Для большей гибкости представления строк или чисел, поддерживаются несколько модификаторов форматов. Модификаторы вставляются между символом процента и буквой, характеризующей формат, например:
[ya@antony ~]$ printf '%50s\n' 'this field is 50 characters wide...' this field is 50 characters wide...
(С кириллицей не работает).
Модификаторы: Любое число Обозначает минимальную ширину колонки, если текст короче, то строки дополняются пробелами. (См. пример выше).
- Альтернативный формат для чисел, см. ниже.
- Выравнивание текста по левому краю (стандарно - по правому краю)
0 Дополняет числа нулями, а не пробелами. Применяется при заданной ширине колонки (в примере 50). Пример:
$ printf '%050d\n' '177' 00000000000000000000000000000000000000000000000177
space Дополняет положительные числа пробелами, а отрицательные знаками "минус" (-).
+ Пишет все числа со знаками плюс или минус.
Альтернативный формат для чисел
%#o Восьмеричные числа пишутся с нулем впереди, если они сами не нулевые:
$ printf '%#0o\n' '177' 0261
%#x, %#X Шестнадцатеричные числа пишутся с 0х или 0Х впереди, если они сами не нулевые:
$ printf '%#x\n' '177' 0xb1
%#g, %#G Числа с плавающей запятой пишутся с последующими нулями, в количестве, определяемом данным разрешением. Обычно последующие нули не пишутся:
$ printf '%#g\n' '17,7' 17,7000
%# со всеми числовыми форматами, кроме d, o, x, X Всегда ставит десятичную запятую, даже если знаков после запятой нет:
$ printf '%#ge\n' '177' 177,000
Точность разрешения
Точность разрешения чисел с плавающей запятой и чисел с удвоенной точностью (double precision) можно регулировать следующим образом:
$ printf "%.20f\n" 4,3 4,30000000000000000017
Внимание: не прозевайте точку в записи формата!
Можно вместо числа знаков поставить астериск, тогда количество знаков ставится перед самим аргументом:
$ printf "%.*f\n" 10 4,3 4,3000000000
Для строк точность разрешения определяет максимальное число выводимых символов (максимальную ширину колонки текста).
Для целых чисел - задает число выводимых знаков (добавляет нули).
Управляющие символы языка Си, работающие с командой printf
\" Двойные кавычки
\NNN Символ с восьмеричным значением NNN (от 1 до 3 цифр)
\\ Обратный слэш (\)
\a Звуковой сигнал
\b Забой
\c Не производить дальнейшую обработку данных
\f Перевод страницы
\n Новая строка
\r Возврат каретки
\v Вертикальная табуляция
\xHH Символ с шестнадцатеричным кодом HH (1 или 2 цифры)
\uHHHH Символ Unicode (ISO/IEC 10646) с шестнадцатеричным кодом HHHH (4 цифры)
\UHHHHHHHH Символ Unicode с шестнадцатеричным кодом HHHHHHHH (8 цифр)
%% Символ %
Еще несколько примеров
1. Вывести шестнадцатеричное число в десятичной форме:
$ printf '%d\n' '-0x41' -65
2. Вывести десятичное число в восьмеричной форме:
$ printf '%o\n' 65 101
3. Узнать кодовый номер буквы А (англ):
$ printf '%d\n' \'A 65
4. Пример, служащий домашним заданием:
$ printf '%b\n' "$0" "$@" /bin/bash
Кто понял, в чем тут дело, сообщите мне, пожалуйста. Я лично не понял.
Опции команды printf
Опция -v ПЕРЕМЕННАЯ_ОКРУЖЕНИЯ
Записывает аргумент в указанную переменную окружения. При этом затирает все, что там было прописано. Осторожно!
$ printf -v PATH '%b\n' '/usr/local/bin' $ printf '%b\n' $PATH /usr/local/bin $ su bash: su: команда не найдена
Хорошо, что в начале статьи я привел пример, в котором была записана моя $PATH, поэтому смог восстановить.
Опции --help и --version общеизвестны и рассмотрены не будут.
Примечание: В мане GNU-версии команды вы не найдете и половины этой информации, а будете отосланы к синтаксису языка Си.
Резюме команды printf
Исследуя подобные команды, получаешь настоящее удовольствие, маны практически отсутствуют, найденные статьи относятся к другим версиям команды. Почти все приходится добывать методом эксперимента. Сколько еще удивительных особенностей таит команда printf, узнают только те, кто станет пользоваться ей в повседневной жизни.
Должен предупредить, что собрал в этой статье все, что сумел "нарыть" по поводу всех версий этой команды. Поэтому некоторые варианты могут не срабатывать в ваших версиях.
Информация взята с open-club.ru