Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2622209
  • 博文数量: 877
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5921
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-05 12:25
个人简介

技术的乐趣在于分享,欢迎多多交流,多多沟通。

文章分类

全部博文(877)

文章存档

2021年(2)

2016年(20)

2015年(471)

2014年(358)

2013年(26)

分类: LINUX

2014-04-27 09:54:06



前几天看到一篇英文的关于bash的printf使用方法,觉得不错,简单的翻译了一下,给大家分享一下,如果错误的地方,请指正,谢谢! (在多位大侠的指导下,终于会发表情啦!


-----这里讲的printf指的是bash的内建命令(bash-builtin),而不是C函数中的printf(),不过它所实现的功能和printf()函数是非常类似的,可以说是echo命令的一个继承和发展,更加接近POSIX标准。

-----使用语法:
  1. printf
复制代码
先举个例子:
  1. SURNAME=china
  2. LASTNAME=unix
  3. printf "Surname: %s\nName: %s\n" "$SURNAME" "$LASTNAME"
  4. Surname: china
  5. Name: unix
复制代码
如果你想把输出作为一个变量,也很简单,只要使用 –v var的形式就可以。
  1. printf -v var "%sxxx"
  2. echo $var
  3. 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格式化输出。
例子:
  1. printf "%s#%s|\n" "xxx" "yyy" "zzz" "ttt" "vvv"
  2. xxx#yyy|
  3. zzz#ttt|
  4. vvv#|
复制代码
<2>如果FORMANT specifies 多于ARGUMENTS的个数时,如果FORMAT是数值(字)格式,则按0处理,如果ARUGENT是字符格式,则按NULL处理。
例子:
  1. printf "%s#%04d#%s\n" "xxx"
  2. xxx#0000#
复制代码
<3>如果FORMAT是数值(字)格式时,需要注意,数字要满足八进制的要求(base8), 因为printf命令会按照bash的数字规则来处理。
例子:
  1. printf "%d\n" "01"
  2. 1

  3. printf "%d\n" "08"
  4. -bash: printf: 08: invalid number
  5. 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 (不知怎么翻译好)
先看个例子吧:
  1. printf "%50s\n" "This field is 50 characters wide..."
  2.                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)也是常见的输出要求,格式为”.”,部分可以是具体的数字,也是”*”;如果是后者,写法上少有差异:
  1. printf "%.*f\n" 10 4
  2. 4.0000000000
  3. printf "%.10f\n" 4
  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.        打印十六进制值:
  1. printf "%d\n" 0x41
  2. 65
  3. printf "%d\n" -0x41
  4. -65
  5. printf "%+d\n" 0x41 # 输出数值为”+”时,不能用printf "%d\n" +0x41的写法。
  6. +65
复制代码
2.        打印十进制值:
  1. printf "%o\n" 65
  2. 101
  3. printf "%05o\n" 65
  4. 00101
复制代码
3.        如果打印”0”呢?
  1. printf "%d\n"
  2. 0
复制代码
4.        打印字符代码(两种方式):
  1. printf "%d\n" \'A
  2. 65
  3. printf "%d\n" "'A"
  4. 65
复制代码
5.        Code 表的打印:
  1. for ((x=0; x <= 127; x++)); do
  2.   printf '%3d | %04o | 0x%02x\n' "$x" "$x" "$x"
  3. done
复制代码
6.        巧妙打印n个”-"
  1. length=40
  2. printf -v line '%*s' "$length"
  3. echo ${line// /-}
  4. ----------------------------------------
复制代码
或者:
  1. length=40
  2. eval printf -v line '%.0s-' {1..$length}
  3. ----------------------------------------
复制代码
7.        原文中还提到了一种替代Date的方法:"%(...)T"(不过我没有运行成功,不知什么原因,大家试试)
  1. printf 'This is week %(%U/%Y)T.\n' -1
  2. This is week 52/2010.
复制代码
原文链接:
阅读(733) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~