Printf: различия между версиями
Langator (обсуждение | вклад) (Новая страница: «== Printf как замена команды echo == Эта команда была создана для замены всем знакомой команды echo...») |
Langator (обсуждение | вклад) м |
||
Строка 4: | Строка 4: | ||
Команда printf выводит АРГУМЕНТ на стандартный вывод (как правило, экран дисплея), используя при этом определенный ФОРМАТ. | Команда printf выводит АРГУМЕНТ на стандартный вывод (как правило, экран дисплея), используя при этом определенный ФОРМАТ. | ||
− | + | <source lang="bash">printf 'ФОРМАТ' 'АРГУМЕНТ'</source> | |
Эта команда была создана для замены всем знакомой команды echo (настолько древней, что даже имя ее автора не известно). | Эта команда была создана для замены всем знакомой команды echo (настолько древней, что даже имя ее автора не известно). | ||
Строка 332: | Строка 332: | ||
Должен предупредить, что собрал в этой статье все, что сумел "нарыть" по поводу всех версий этой команды. Поэтому некоторые варианты могут не срабатывать в ваших версиях. | Должен предупредить, что собрал в этой статье все, что сумел "нарыть" по поводу всех версий этой команды. Поэтому некоторые варианты могут не срабатывать в ваших версиях. | ||
+ | == Ссылки == | ||
+ | [http://open-club.ru/main/reading/HuMan_printf open-club.ru] | ||
− | + | [[Категория:Man]] | |
− |
Текущая версия на 18:26, 15 апреля 2011
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, узнают только те, кто станет пользоваться ей в повседневной жизни.
Должен предупредить, что собрал в этой статье все, что сумел "нарыть" по поводу всех версий этой команды. Поэтому некоторые варианты могут не срабатывать в ваших версиях.