清单 23. 使用 sed 对行进行编号
[ian@echidna lpi103-2]$ sed '=' text2
1
9
plum
2
3
banana
3
10
apple
[ian@echidna lpi103-2]$ sed '=' text2|sed 'N;s/\n//'
19
plum
23
banana
310
apple
和我们期望的还有一定差距!我们真正想要的是将编号放到一列中,并在行的前面留一些空格。在清单 24 中,我们输入几行命令(注意第二个 > 提示)。研究这个例子并参考下面的解释。
清单 24. 再一次使用 sed 对行进行编号
[ian@echidna lpi103-2]$ cat text1 text2 text1 text2>text6 [ian@echidna lpi103-2]$ ht=$(echo -en "\t") [ian@echidna lpi103-2]$ sed '=' text6|sed "N > s/^/ / > s/^.*\(......\)\n/\1$ht/" 1 1 apple 2 2 pear 3 3 banana 4 9 plum 5 3 banana 6 10 apple 7 1 apple 8 2 pear 9 3 banana 10 9 plum 11 3 banana 12 10 apple
下面解释了我们执行的操作:
我们首先使用 cat 从 text1 和 text2 的副本中创建一个包含 12 行的文件。如果编号的数位相同的话,那么对列中的编号进行格式化则没有什么乐趣。 bash shell 使用制表键表示命令结束,因此当我们需要一个真正的制表符时,使用一个专用 tab 字符将非常方便。我们使用 echo 命令实现这点并将字符保存到 shell 变量 ‘ht’ 中。 像前面一样,我们创建了一个包含行号(后跟数据行)的流,然后通过另一个 sed 副本进行过滤。 我们将第二个行读入到模式空间中。 在模式的开始部分,我们将 6 个空格添加到行号前面,作为前缀(使用 ^ 表示)。 随后使用换行符前面的最后 6 个字符再加上制表符来替换换行符前面的所有行内容。这将把行号排列到输出行的前 6 个列中。注意 ‘s’ 命令的左侧使用 ‘\(’ 和 ‘\)’ 标记我们希望在右侧使用的字符。在右侧部分中,我们将第一个被标记的集合(在本例中只有一个集合)引用为 \1。注意,我们的命令被包含在双引号之间,因此将对 $ht 执行替换。sed 的第四版包含 info 格式的文档,并附带了许多出色的示例。这些内容都未包含在较早的 3.02 版本中。GNU sed 将接受 sed --version 来显示该版本。