![b4ec2ac033ef584c5cc1edd22943666a.png](https://i-blog.csdnimg.cn/blog_migrate/e3ec02cf8622c1b4ef5f803ee59430f2.jpeg)
本章继续讨论与文本相关的工具,重点讲一些用于格式化文本输出而非改变文本自身内容的命令。这些命令通常用于文本的打印,而“打印”这一主题将在下一章介绍。本章将要讨论的命令如下所示。
- nl:对行进行标号。
- fold:设定文本行长度。
- fmt:简单的文本格式化工具。
- pr:格式化打印文本。
- printf:格式化并打印数据。
- grof:文档格式化系统。
1 简单的格式化工具
- nl——对行进行标号
nl 命令是一个非常神秘的工具,用于完成一个非常简单的任务:对行进行编号。就其最简单用法,与cat –n很相似。
![7f87d06fe06078833b3d24b6a6aaa97b.png](https://i-blog.csdnimg.cn/blog_migrate/291d711eff665c1350a022bf30a699c6.jpeg)
![20f688e1726352c49f8076a251af2e05.png](https://i-blog.csdnimg.cn/blog_migrate/2ec7b9a859f76964646240932ef0bed3.jpeg)
和cat命令一样,nl既支持多个文件名作为命令行参数,也支持标准输入。然而,nl可以进行多种复杂的编号,因为它有许多参数选项,且支持原始形式的标记。
nl 进行标号时支持一个叫做逻辑页的概念,所以它可以重置(重新开始)数值序列。通过合理运用参数选项,nl 可以设置起始编号为特定的值,并在有限的范围内设置其格式。逻辑页可以进一步分解为逻辑页标题、正文和页脚。在每一个部分中,行号都可以重置并/或分配不同的风格。如果nl的输入参数是多个文件,那么nl会把它们当作一个文本流整体。文本流中的每一个部分都由一些看起来非常奇怪的标记来区别,表21-1列出了部分标记。
![921477a2dfdbb97beec787bb43924d45.png](https://i-blog.csdnimg.cn/blog_migrate/d2aff2327493f75db308db170cb87f50.jpeg)
![cfe0d8a5ab13972f40c480d5a0f302b1.png](https://i-blog.csdnimg.cn/blog_migrate/930b238974d32f8b258eeb5e6f65de20.jpeg)
表21-1 中的每一个标记元素在一行中只允许出现一次。每次处理完一个标记元素后,nl便将其从文本流中删除。
表21-2列出了nl的常用选项。
![e5e533dec974f526feb282c0779374db.png](https://i-blog.csdnimg.cn/blog_migrate/52e94217bec1d242715fbed753c0f79f.jpeg)
- fold——将文本中的行长度设定为指定长度
fold是一个将文本行以指定长度分解的操作。与其他命令类似,fold支持一个或多个文本文件或是标准输入作为输入参数。向fold输入一个简单的文本流,便可了解其工作方式。
![e0502c194bd0ab90bd907f146c5dd785.png](https://i-blog.csdnimg.cn/blog_migrate/a2e55ffb7930a989670a5620b3e5a9dc.png)
这样,我们便能明白fold到底完成了什么操作。echo命令输出的文本被指定了-w选项的fold分解成了片段。本例中,指定了行的宽度为12个字符。如果没有指定行宽,则默认是80个字符宽。请注意,fold在断行时并不会考虑单词边界。而增加-s选项,可使fold在到达width字符数前的最后一个有效空格处将原文本行断开,示例如下。
![87cb44b43bb08e54d531978df2d4529c.png](https://i-blog.csdnimg.cn/blog_migrate/e0d3737241e162dd03c39f15cccd69ba.png)
- fmt——简单的文本格式化工具
fmt命令同样会折叠文本,另外还包括更多其他功能。它既可以处理文件也可以处理标准输入,并对文本流进行段落格式化。就其基本功能而言,它可以在保留空白行和缩进的同时对文本行进行填充和连接。
![e9ca9bc8ae5e3cf0b93022d6dce19f05.png](https://i-blog.csdnimg.cn/blog_migrate/390c4b35cfb6631419a9e533e6a63d36.jpeg)
这个输出结果还真是奇怪。也许,实际上我们应该认真地阅读一遍下面的文字,因为它解释了事情发生的原委。
默认情况下,空白行、单词之间的空格和缩进都保留在输出结果中;不同缩进量的连续输入行并不进行拼接;制表符会在输入中扩展并直接输出。
所以,fmt保留了第一行的缩进。幸运的是,fmt提供了一个参数选项以修正这一问题。
![6b8fac24a12b4452fb93f3d6738ccb51.png](https://i-blog.csdnimg.cn/blog_migrate/2f81ad6b8f5fec7bcca9edc714ddb098.jpeg)
这样一来,输出结果看起来顺眼了很多。由此可见,通过增加-c选项,我们便得到了理想输出结果。
![27734befe9f011161f0201c79a6c633f.png](https://i-blog.csdnimg.cn/blog_migrate/bd82d78245d9f3e449fe80ef6e12655c.jpeg)
- pr——格式化打印文本
Pr命令用于给文本标页码。打印文本时,通常希望将输出内容分成几页,并且每页的顶部和底部都留出几行空白行,这些空白行可以用于插入页眉和页脚。
- printf——格式化并打印数据
与本章中涉及的其他命令不一样,printf命令并不适用于管道传输(也就是说它不支持标准输入),而且在命令行应用中它也不常见(多应用于脚本文件)。那么它到底为什么会这么重要?因为它有如此广泛的应用范围。
printf(短语print formatted的缩写)起初是为C语言开发的,后来许多编程语言也都实现了这一功能,也包括shell环境。事实上,在bash中,printf是内置的。
printf的用法如下。
printf“format”arguments
该命令行给出了一个包含格式说明的字符串,然后将该格式应用于arguments所代表的输入内容,最后格式化结果送至标准输出。如下就是一个简单例子。
![1ab0a5e1b98f03f1a65c6886e97cfc19.png](https://i-blog.csdnimg.cn/blog_migrate/c2f64210b9af3b424a53693179ba251e.png)
该格式化字符串可以包含文字文本(如“I formatted the string”)、转义字符(如n,即换行符)以及以%开头的表示转换规格的字符序列。上例中,转换规格%s用于格式化字符串foo并将其结果输出。再看下面一个例子。
![4abe23cd9a62363b448f806e13509c2d.png](https://i-blog.csdnimg.cn/blog_migrate/12d3fb6e852f4b0f11e5354f0e408014.png)
以上可以看出,%s所代表的转换规格被字符串foo取代。s表示格式化字符串数据,其他类型的数据则用其他指定字符表示。表21-4列出了常用的数据类型。
![1a9f65827090e43f909a0995a6e96d53.png](https://i-blog.csdnimg.cn/blog_migrate/70a704f16b408412ca4207450aa0aaa8.jpeg)
![2063a60c456e0ec12f6b3ad8c1d4b5e6.png](https://i-blog.csdnimg.cn/blog_migrate/4e290468b8fdbe4197f4932b7bb4d3ca.png)
![8e9629601e76fbe43592ba9fbc6d1cb1.png](https://i-blog.csdnimg.cn/blog_migrate/2afcea018731da8bdacc69f2bbf8a058.png)
表21-6列出了一些不同格式化实例。
![ca232f379f1c6a6f8602c6d0d6cc154c.png](https://i-blog.csdnimg.cn/blog_migrate/d06a29fb87e75460e9a885af431526a0.jpeg)
同样,printf通常用于脚本文件的表格数据格式化操作,而并不会直接应用于命令行。不过,我们仍然可以用其解决各种各样的格式化问题。首先,我们可以利用printf输出一些由制表符隔开的字段。