bash之printf
(2013-08-19 16:31:51)
前几天看到一篇英文的关于bash的printf使用方法,觉得不错,简单的翻译了一下
-----这里讲的printf指的是bash的内建命令(bash-builtin),而不是C函数中的printf(),不过它所实现的功能和printf()函数是非常类似的,可以说是echo命令的一个继承和发展,更加接近POSIX标准。
-----使用语法:
先举个例子:
- SURNAME=china
- LASTNAME=unix
- printf "Surname: %s\nName:
%s\n" "$SURNAME" "$LASTNAME"
- Surname: china
- Name: unix
复制代码
如果你想把输出作为一个变量,也很简单,只要使用
–v var的形式就可以。
- printf -v var
"%sxxx"
- echo $var
- xxx
复制代码
-----FORMAT
部分内容很多放到后,先说下ARGUMENTS,
一般情况下,ARGUMENT是一个字符(STRING),当然也可以是数值(字),不过有特定的格式,如下(为了尊重原“注”,这里给出英文注释):
|
Number-Format |
Description |
|
N |
A normal decimal number |
|
0N |
An octal number |
|
0xN |
A hexadecimal number |
|
0XN |
A hexadecimal number |
|
"X |
(a literal double-quote infront of a character): interpreted as
number (underlying codeset)don't forget
escaping |
|
'X |
(a literal single-quote infront of a character): interpreted as
number (underlying codeset)don't forget
escaping |
<1>如果FORMAT
specifies少于ARGUMENTS的个数时,printf会按照设定好的格式,把所有的ARGUMENTS格式化输出。
例子:
- printf "%s#%s|\n" "xxx"
"yyy" "zzz" "ttt" "vvv"
- xxx#yyy|
- zzz#ttt|
- vvv#|
复制代码
<2>如果FORMANT
specifies
多于ARGUMENTS的个数时,如果FORMAT是数值(字)格式,则按0处理,如果ARUGENT是字符格式,则按NULL处理。
例子:
- printf "%s#d#%s\n"
"xxx"
- xxx#0000#
复制代码
<3>如果FORMAT是数值(字)格式时,需要注意,数字要满足八进制的要求(base8),
因为printf命令会按照bash的数字规则来处理。
例子:
- printf "%d\n"
"01"
- 1
- printf "%d\n"
"08"
- -bash: printf: 08: invalid
number
- 0
复制代码
-----下面开始说FORMAT部分。
Printf对FORMAT的解释方法实质上和C函数的printf是一样的,它所识别的字符只有“diouxXfeEgGcs”,使用方法就百分号加上这些字符,”%+字符”。如果要打印百分号符,也很简单,double下,”%%”。
对以上“%+字符”的解释如下:
|
Format |
Description |
|
%b |
Print the associated argument while interpreting backslash escapes
in there |
|
%q |
Print the associated argument shell-quoted,
reusable as input |
|
%d |
Print the associated argument as signed
decimal number |
|
%i |
Same as %d |
|
%o |
Print the associated argument as unsigned
octal number |
|
%u |
Print the associated argument as unsigned
decimal number |
|
%x |
Print the associated argument as unsigned
hexadecimal number with lower-case
hex-digits (a-f) |
|
%X |
Same as %x, but with upper-case hex-digits (A-F) |
|
%f |
Interpret and print the associated argument
as floating
point number |
|
%e |
Interpret the associated argument as double, and print
it in ±e format |
|
%E |
Same as %e, but with an upper-case E in the printed format |
|
%g |
Interprets the associated argument as double, but
prints it like %f or %e |
|
%G |
Same as %g, but print it like %E |
|
%c |
Interprets the associated argument as character: only the first
character of a given argument is printed |
|
%s |
Interprets the associated argument literally as string |
|
%b |
Interprets the associated argument as a string and interpreting
escape sequences in it |
|
%q |
Prints the associated argument in a format, that it can be re-used
as shell-input (escaped spaces etc..) |
|
%n |
No conversion or printing is done. Assigns the number of so far
printed characters to the variable named in the corresponding
argument (similat to C's printf) |
|
%(FORMAT)T |
output the date-time string resulting from using FORMAT as a format
string for strftime(3). The associated argument is the number of
seconds since Epoch, or -1 (current time) or -2 (shell startup
time) |
|
%% |
No conversion is done. Produces a % (percent sign) |
既然说printf,在功能上,是echo的继承和发展,那它就一定有更加flexible的设计,下面我们来例举一下。
<1> Modifiers (不知怎么翻译好)
先看个例子吧:
- printf "Ps\n" "This field
is 50 characters wide..."
-
This field
is 50 characters wide...
复制代码
这个例子中的”50”就是一个Modifier,可以实现向左对齐,字符宽度50,这也是我们最为常见的一种文本输出需求。
下面让我们看看,还有什么其他的Modifiers:
|
Field output
format
|
|
|
Any
number: Specifies a minimum field
width, if the text to print is smaller, it's padded with
spaces, if the text is bigger, the field is expanded
|
|
.
|
The
dot: Together with a field width, the field
is not expanded
when the text is bigger, the text is cutted instead. "%.s" is an
undocumented equivalent for "%.0s", which will force a field width
of zero, effectively hiding the field from output
|
|
*
|
The
asterisk: the width is given as argument before the string
or number. Usage (the "*" corresponds to the "20"): printf "%*s\n"
20 "test string"
|
|
#
|
"Alternative format" for numbers: see table below
|
|
-
|
Left-bound text
printing in the field (standard is right-bound)
|
|
0
|
Pads numbers with zeros, not spaces
|
|
|
Pad a positive number with a space, where a minus (-) is for
negative numbers
|
|
+
|
Prints all numbers signed (+
for positive, - for negative)
|
|
Alternative
Format |
|
%#o |
The octal number is printed with a leading zero, unless it's zero
itself |
|
%#x, %#X |
The hex number is printed with a leading "0x"/"0X", unless it's
zero |
|
%#g, %#G |
The float number is printed with trailing
zeros until the number of digits for the
current precision is reached (usually trailing zeros are not
printed) |
|
all number formats except %d, %o, %x, %X |
Always print a decimal point in the output, even if no digits
follow it |
此外,精度(precision)也是常见的输出要求,格式为”.”,部分可以是具体的数字,也是”*”;如果是后者,写法上少有差异:
- printf "%.*f\n" 10
4
- 4.0000000000
- printf "%.10f\n"
4
- 4.0000000000
复制代码
<如果是字符串的话,DIGIT
定义的是最大的field width, 如果是整数,则是数字输出的个数,不足是有”0”补齐>
下面是一些逃逸字符(Escape codes)的写法:
|
Code |
Description |
|
\\ |
Prints the character \ (backslash) |
|
\a |
Prints the alert character (ASCII code 7 decimal) |
|
\b |
Prints a backspace |
|
\f |
Prints a form-feed |
|
\n |
Prints a newline |
|
\r |
Prints a carriage-return |
|
\t |
Prints a horizontal tabulator |
|
\v |
Prints a vertical tabulator |
|
\" |
Prints a ' |
|
\? |
Prints a ? |
|
\ |
Interprets as octal number
and prints the corresponding character from the character set |
|
\0 |
same as \ |
|
\x |
Interprets as hexadecimal number
and prints the corresponding character from the character set
(3
digits) |
|
\u |
same as \x, but 4 digits |
|
\U |
same as \x, but 8 digits |
-----最后列举一些例子,加深理解!
1.
打印十六进制值:
- printf "%d\n"
0x41
- 65
- printf "%d\n"
-0x41
- -65
- printf "%+d\n" 0x41 #
输出数值为”+”时,不能用printf "%d\n" +0x41的写法。
- +65
复制代码
2.
打印十进制值:
- printf "%o\n" 65
- 101
- printf "o\n" 65
- 00101
复制代码
3.
如果打印”0”呢?
4.
打印字符代码(两种方式):
- printf "%d\n" \'A
- 65
- printf "%d\n"
"'A"
- 65
复制代码
5.
Code
表的打印:
- for ((x=0; x <= 127;
x++)); do
-
printf '= | o | 0xx\n' "$x"
"$x" "$x"
- done
复制代码
6.
巧妙打印n个”-"
- length=40
- printf -v line '%*s'
"$length"
- echo ${line// /-}
-
----------------------------------------
复制代码
或者:
- length=40
- eval printf -v line '%.0s-'
{1..$length}
-
----------------------------------------
复制代码
7.
原文中还提到了一种替代Date的方法:"%(...)T"(不过我没有运行成功,不知什么原因,大家试试)
- printf 'This is week
%(%U/%Y)T.\n' -1
- This is week 52/2010.
复制代码
喜欢
0
赠金笔
加载中,请稍候......