printf는 format string에 따라 문자열과 숫자를 변환해 표준 출력으로 내보내는 명령이다. 많은 shell이 builtin으로 제공하며, GNU/Linux에서는 GNU coreutils의 외부 명령도 함께 사용할 수 있다.
printf FORMAT [ARGUMENT…]echo보다 개행, escape, field width와 숫자 format을 명시적으로 제어할 수 있어 portable shell script에 적합하다.
대부분의 Unix 계열 shell에는 printf builtin이 이미 포함되어 있다. 아래 명령은 외부 GNU printf가 필요할 때 GNU coreutils package를 설치하는 방법이다.
sudo apt update sudo apt install coreutils
sudo dnf install coreutils
macOS에는 system printf가 기본 제공된다. GNU coreutils 구현이 필요하면 Homebrew formula를 설치한다. macOS 기본 명령과 이름이 겹치므로 Homebrew 구현은 일반적으로 gprintf로 설치된다.
brew install coreutils gprintf --version
GNU coreutils project가 공식 배포하는 native Windows winget package는 확인되지 않는다. WSL 또는 사용하는 Unix-compatible shell 환경에서 제공하는 printf를 사용하고 해당 환경의 문서를 확인한다.
command -V printf env printf --version
command -V printf는 현재 shell이 builtin, alias 또는 외부 명령 중 무엇을 실행하는지 보여 준다.env printf –version은 PATH에서 외부 명령을 실행한다. POSIX builtin에는 –version이 없을 수 있다.printf FORMAT [ARGUMENT]... printf OPTION
printf FORMAT [ARGUMENT…]: format string을 필요한 만큼 재사용해 모든 argument를 출력printf –help: GNU 외부 명령의 help 출력printf –version: GNU 외부 명령의 version 출력printf – FORMAT [ARGUMENT…]: -로 시작하는 format을 operand로 처리%s: argument를 string으로 출력%d, %i: signed decimal integer로 출력%u, %o, %x, %X: unsigned decimal, octal, hexadecimal로 출력%f, %e, %E, %g, %G: floating-point 형식으로 출력%c: argument의 첫 character를 출력'': literal percent sign(''%'')을 출력
* ''%b'': argument 안의 backslash escape를 해석하는 GNU/shell extension
* ''%q'': shell input으로 재사용할 수 있게 quote하는 GNU/Bash extension
Field width와 precision은 conversion directive에 함께 지정할 수 있다.
<code bash>
printf '%-12s %8.2f\n' "item" 19.5
printf '%04d\n' 7
</code>
==== Backslash escapes ====
* ''\\'': backslash
* ''\a'', ''\b'', ''\f'', ''\n'', ''\r'', ''\t'', ''\v'': alert, backspace, form feed, newline, carriage return, tab, vertical tab
* ''\c'': 이후 출력을 중단
* ''\NNN'': octal byte value
* ''\xHH'': hexadecimal byte value(GNU extension)
* ''\uHHHH'', ''\UHHHHHHHH'': Unicode character(GNU extension)
===== Examples =====
==== String and newline ====
<code bash>
printf '%s\n' "hello world"
printf 'name=%s\n' "$USER"
</code>
==== Repeated format ====
하나의 format은 남은 argument에 반복 적용된다.
<code bash>
printf '%s\n' alpha beta gamma
</code>
==== Table formatting ====
<code bash>
printf '%-12s %8s\n' NAME COUNT
printf '%-12s %8d\n' apples 12
printf '%-12s %8d\n' oranges 7
</code>
==== Escape and Unicode ====
<code bash>
printf 'first\tsecond\n'
env printf '\u20AC %.2f\n' 14.95
</code>
==== Safe variable output ====
<code bash>
value='%s%s%s'
printf '%s\n' "$value"
</code>
<note important>
외부 입력이나 변수를 format 위치에 직접 넣지 않는다. ''printf "$value"'' 대신 고정 format을 둔 ''printf '%s\n' "$value"'' 형태를 사용한다. 입력에 ''%'' 또는 backslash sequence가 있으면 예상하지 못한 변환이나 오류가 발생할 수 있다.
</note>
===== Troubleshooting =====
==== --help 또는 --version이 그대로 출력됨 ====
shell builtin이 GNU 외부 명령보다 먼저 실행된 경우다. 현재 해석 결과를 확인하고 외부 명령을 명시한다.
<code bash>
command -V printf
env printf --help
</code>
==== 숫자 변환 오류 ====
숫자 conversion에 숫자가 아닌 argument를 전달하면 diagnostic과 non-zero exit status가 발생할 수 있다. locale에 따라 floating-point decimal separator 해석도 달라질 수 있으므로 machine-readable output에는 필요하면 ''LC_ALL=C''를 지정한다.
<code bash>
LC_ALL=C printf '%.2f\n' 3.5
</code>
==== 처음이 -인 문자열 출력 ====
GNU 외부 명령에서는 ''--''로 option parsing을 끝낸다. builtin의 ''--'' 지원 여부는 shell마다 다를 수 있으므로 portable script에서는 고정 ''%s'' format을 사용하는 편이 안전하다.
<code bash>
printf '%s\n' '--help'
env printf -- '--help\n'
</code>
===== Compatibility =====
* POSIX ''printf''의 기본 synopsis는 ''printf FORMAT [ARGUMENT...]''이다.
* ''%s'', 정수·floating-point conversion과 기본 C-style escape가 중심이며, ''%q'', ''\xHH'', ''\uHHHH'', ''\UHHHHHHHH'' 같은 extension은 모든 구현에서 지원되지 않는다.
* ''printf''가 builtin이면 GNU coreutils의 ''--help''와 ''--version'' option이 적용되지 않을 수 있다.
* 같은 script를 여러 shell과 operating system에서 실행한다면 extension 사용을 피하고 대상 shell의 builtin 문서를 함께 확인한다.
===== Help =====
++++ /usr/bin/printf --help |
<code text>
Usage: /usr/bin/printf FORMAT [ARGUMENT]...
or: /usr/bin/printf OPTION
Print ARGUMENT(s) according to FORMAT, or execute according to OPTION:
--help display this help and exit
--version output version information and exit
FORMAT controls the output as in C printf. Interpreted sequences are:
\" double quote
\\ backslash
\a alert (BEL)
\b backspace
\c produce no further output
\e escape
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\NNN byte with octal value NNN (1 to 3 digits)
\xHH byte with hexadecimal value HH (1 to 2 digits)
\uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)
\UHHHHHHHH Unicode character with hex value HHHHHHHH (8 digits)
a single %
%b ARGUMENT as a string with '\' escapes interpreted,
except that octal escapes are of the form \0 or \0NNN
%q ARGUMENT is printed in a format that can be reused as shell input,
escaping non-printable characters with the proposed POSIX $ syntax.and all C format specifications ending with one of diouxXfeEgGcs, with ARGUMENTs converted to proper type first. Variable widths are handled.
NOTE: your shell may have its own version of printf, which usually supersedes the version described here. Please refer to your shell's documentation for details about the options it supports.
GNU coreutils online help: <https://www.gnu.org/software/coreutils/> Report printf translation bugs to <https://translationproject.org/team/> Full documentation at: <https://www.gnu.org/software/coreutils/printf> or available locally via: info '(coreutils) printf invocation' </code> ++++