• ——–
    \:\:
    s/([0-9]{2})/([0-9]{2})/([0-9]{4})$/\3-\1-\2/
    $ i
    \:

    End Of Report
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28



这个脚本现在加入了 nl 的逻辑页面标记并且在报告的最后加了一个 footer。记得我们在我们的标记中必须两次使用反斜杠, 因为他们通常被 sed 解释成一个转义字符。

下一步,我们将结合 sort, sed, nl 来生成我们改进的报告:

```bash
$ sort -k 1,1 -k 2n distros.txt | sed -f distros-nl.sed | nl
Linux Distributions Report
Name Ver. Released
---- ---- --------
1 Fedora 5 2006-03-20
2 Fedora 6 2006-10-24
3 Fedora 7 2007-05-31
4 Fedora 8 2007-11-08
5 Fedora 9 2008-05-13
6 Fedora 10 2008-11-25
7 SUSE 10.1 2006-05-11
8 SUSE 10.2 2006-12-07
9 SUSE 10.3 2007-10-04
10 SUSE 11.0 2008-06-19
11 Ubuntu 6.06 2006-06-01
12 Ubuntu 6.10 2006-10-26
13 Ubuntu 7.04 2007-04-19
14 Ubuntu 7.10 2007-10-18
15 Ubuntu 8.04 2008-04-24
End Of Report

我们的报告是一串命令的结果,首先,我们给名单按发行版本和版本号(表格1和2处)进行排序,然后我们用 sed 生产结果, 增加了 header(包括了为 nl 增加的逻辑页面标记)和 footer。最后,我们按默认用 nl 生成了结果,只数了属于逻辑页面的 body 部分的 文本流的行数。

fold - 限制文件行宽

文本的行限制到特定的宽的过程。

1
2
3
4
5
$ echo "The quick brown fox jumped over the lazy dog." | fold -w 12
The quick br
own fox jump
ed over the
lazy dog.

这里我们看到了 fold 的行为。这个用 echo 命令发送的文本用 -w 选项分解成块。在这个例子中,我们设定了行宽为12个字符。 如果没有字符设置,默认是80。注意到文本行不会因为单词边界而不会被分解。增加的 -s 选项将让 fold 分解到最后可用的空白字符,即会考虑单词边界。

1
2
3
4
5
6
$ echo "The quick brown fox jumped over the lazy dog." | fold -w 12 -s
The quick
brown fox
jumped over
the lazy
dog.

fmt - 一个简单的文本格式器

同样折叠文本,外加很多功能。

让我们重新格式这个文本并且让它成为一个50 个字符宽的项目。我们能用 -w 选项对文件进行处理:

1
2
$ fmt -w 50 fmt-info.txt | head

默认情况下,输出会保留空行,单词之间的空格,和缩进;持续输入的具有不同缩进的文本行不会连接在一起;tab 字符在输入时会展开,输出时复原 。

所以,fmt 会保留第一行的缩进。幸运的是,fmt 提供了一个选项来更正这种行为:通过添加 -c 选项,现在我们得到了所期望的结果。

-p 选项可以格式文件选中的部分,通过在开头使用一样的符号。

1
2
3
4
5
6
7
8
$ cat > fmt-code.txt
# This file contains code with comments.
# This line is a comment.
# Followed by another comment line.
# And another.
This, on the other hand, is a line of code.
And another line of code.
And another.

使用 fmt,我们能格式注释并且 不让代码被触及。

1
2
3
4
5
6
7
$ fmt -w 50 -p '# ' fmt-code.txt
# This file contains code with comments.
# This line is a comment. Followed by another
# comment line. And another.
This, on the other hand, is a line of code.
And another line of code.
And another.

注意相邻的注释行被合并了

pr – 格式化打印文本

pr 程序用来把文本分页。当打印文本的时候,经常希望用几个空行在输出的页面的顶部或底部添加空白。此外,这些空行能够用来插入到每个页面的页眉或页脚。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ pr -l 15 -w 65 distros.txt
2008-12-11 18:27 distros.txt Page 1
SUSE 10.2 12/07/2006
Fedora 10 11/25/2008
SUSE 11.0 06/19/2008
Ubuntu 8.04 04/24/2008
Fedora 8 11/08/2007
2008-12-11 18:27 distros.txt Page 2
SUSE 10.3 10/04/2007
Ubuntu 6.10 10/26/2006
Fedora 7 05/31/2007
Ubuntu 7.10 10/18/2007
Ubuntu 7.04 04/19/2007

在上面的例子中,我们用 -l 选项(页长)和 -w 选项(页宽)定义了宽65列,长15行的一个“页面”。 pr 为 distros.txt 中的内容编订页码,用空行分开各页面,生成了包含文件修改时间、文件名、页码的默认页眉。 pr 指令拥有很多调整页面布局的选项,我们将在下一章中进一步探讨。

printf – Format And Print Data

在 bash 中, printf 是内置的。

1
printf “format” arguments

首先,发送包含有格式化描述的字符串的指令,接着,这些描述被应用于参数列表上。格式化的结果在标准输出中显示。下面是一个小例子:

1
2
$ printf "I formatted the string: %s\n" foo
I formatted the string: foo

格式字符串可能包含文字文本(如“我格式化了这个字符串:” “I formatted the string:”),转义序列(例如\n,换行符)和以%字符开头的序列,这被称为转换规范。在上面的例子中,转换规范 %s 用于格式化字符串 “foo” 并将其输出在命令行中。我们再来看一遍:

1
2
$ printf "I formatted '%s' as a string.\n" foo
I formatted 'foo' as a string.

printf 转换规范组件

组件 描述
d 将数字格式化为带符号的十进制整数
f 格式化并输出浮点数
o 将整数格式化为八进制数
s 将字符串格式化
x 将整数格式化为十六进制数,必要时使用小写a-f
X 与 x 相同,但变为大写
% 打印 % 符号 (比如,指定 “%%”)
1
2
$ printf "%d, %f, %o, %s, %x, %X\n" 380 380 380 380 380 380
380, 380.000000, 574, 380, 17c, 17C

由于我们指定了六个转换符,我们还必须为 printf 提供六个参数进行处理。下面六个结果展示了每个转换符的效果。 可将可选组件添加到转换符以调整输出。

1
%[flags][width][.precision]conversion_specification

使用多个可选组件时,必须按照上面指定的顺序,以便准确编译。以下是每个可选组件的描述:

printf 转换规范组件

组件 描述
flags 有5种不同的标志:
# – 使用“备用格式”输出。这取决于数据类型。对于o(八进制数)转换,输出以0为前缀.对于x和X(十六进制数)转换,输出分别以0x或0X为前缀。
0–(零) 用零填充输出。这意味着该字段将填充前导零,比如“000380”。
- – (破折号) 左对齐输出。默认情况下,printf右对齐输出。
‘ ’ – (空格) 在正数前空一格。
+ – (加号) 在正数前添加加号。默认情况下,printf 只在负数前添加符号。
width 指定最小字段宽度的数。
.precision 对于浮点数,指定小数点后的精度位数。对于字符串转换,指定要输出的字符数。

以下是不同格式的一些示例:

print 转换规范示例

自变量 格式 结果 备注
380 “%d” 380 简单格式化整数。
380 “%#x” 0x17c 使用“替代格式”标志将整数格式化为十六进制数。
380 “%05d” 00380 用前导零(padding)格式化整数,且最小字段宽度为五个字符。
380 “%05.5f” 380.00000 使用前导零和五位小数位精度格式化数字为浮点数。由于指定的最小字段宽度(5)小于格式化后数字的实际宽度,因此前导零这一命令实际上没有起到作用。
380 “%010.5f” 0380.00000 将最小字段宽度增加到10,前导零现在变得可见。
380 “%+d” +380 使用+标志标记正数。
380 “%-d” 380 使用-标志左对齐
abcdefghijk “%5s” abcedfghijk 用最小字段宽度格式化字符串。
abcdefghijk “%d” abcde 对字符串应用精度,它被从中截断。

再次强调,printf 主要用在脚本中,用于格式化表格数据,而不是直接用于命令行。

1
2
3
4
$ printf "%s\t%s\t%s\n" str1 str2 str3
str1 str2 str3
$ printf "Line: %05d %15.3f Result: %+15d\n" 1071 3.14156295 32589
Line: 01071 3.142 Result: +32589
1
2
3
4
5
6
7
8
9
10
11
12
13
$ printf "<html>\n\t<head>\n\t\t<title>%s</title>\n
\t</head>\n\t<body>\n\t\t<p>%s</p>\n\t</body>\n</html>\n" "Page Tit
le" "Page Content"
<html>
<head>
<title>Page Tit
le</title>

</head>
<body>
<p>Page Content</p>
</body>
</html>

文件格式化系统

Document Formatting Systems

groff

groff 是一套用GNU实现 troff 的程序。它还包括一个脚本,用来模仿 nroff 和其他 roff 家族。

roff 及其后继制作格式化文档的方式对现代用户来说是相当陌生的。今天的大部分文件都是由能够一次性完成排字和布局的文字处理器生成的。 在图形文字处理器出现之前,需要两步来生成文档。首先用文本编辑器排字,接着用诸如 troff 之类的处理器来格式化。 格式化程序的说明通过标记语言的形式插入到已排好字的文本当中。 类似这种过程的现代例子是网页。它首先由某种文本编辑器排好字,然后由使用 HTML 作为标记语言的 Web 浏览器渲染出最终的页面布局。