|

楼主 |
发表于 2004-4-29 18:10:27
|
显示全部楼层

作为记录的行
第 1 页(共8 页)
许多 Linux 实用程序将文件视为面向行的记录或数据的集合。这样提供了聚合那些同时对人可读和便于使用工具来处理的数据集合的便利途径。一个简单的技巧就是将每个新行字符看作是记录之间的分隔符,其中每个记录具有类似的格式。
从实用的角度出发,面向行的记录通常应该具有相对有限的长度,或许不应超过几百个字符。虽然没有哪一个文本实用程序内置了这样的限制,但是即使使用自动换行或水平滚动,人类的眼睛也不适应观看过长的行。对于这样的情况,或者可以使用更复杂的结构化数据格式,或者可以将记录分隔到多行(或许还会作一些 grep 能够识别的标记)。作为一个简单的例子,您可以使用前缀字符来保持分层结构的多行数据格式:
- $ cat multiline
- A Alice Aaronson
- B System Administrator
- C 99 9th Street
- A Bob Babuk
- B Programmer
- C 7 77th Avenue
- $ grep '^A ' multiline # names only
- A Alice Aaronson
- A Bob Babuk
- $ grep '^C ' multiline # address only
- C 99 9th Street
- C 7 77th Avenue
-
复制代码
来自这些 grep 过滤器之一的输出是一个适用的新行字符分隔的部分记录集合,这些集合带有您感兴趣的那些字段。
cut
第 2 页(共8 页)
实用程序 cut 将文件中的字段写到标准输出上,其中每行被看作是分隔的字段集合。默认的分隔字符是制表符,但是这可以使用简短形式的选项 -d <DELIM> 或者完整形式的选项 --delimiter=<DELIM>来改变。
您可以使用 -f 开关来选择一个或多个字段。-c 开关则从每行中选择特定的字符位置。两个开关都接受逗号分隔的数字或范围作为参数(包括非封闭范围)。例如,下面的文件 employees 是制表符分隔的:
- $ cat employees
- Alice Aaronson System Administrator 99 9th Street
- Bob Babuk Programmer 7 77th Avenue
- Carol Cavo Manager 111 West 1st Blvd.
- $ hexdump -n 50 -c employees
- 0000000 A l i c e A a r o n s o n \t S
- 0000010 y s t e m A d m i n i s t r a
- 0000020 t o r \t 9 9 9 t h S t r e e
- 0000030 t \n
- 0000032
- $ cut -f 1,3 employees
- Alice Aaronson 99 9th Street
- Bob Babuk 7 77th Avenue
- Carol Cavo 111 West 1st Blvd.
- $ cut -c 1-3,20,25- employees
- Alieministrator 99 9th Street
- Bobr7th Avenue
- Car1est 1st Blvd.
-
复制代码
后面的例子将使用制表符之外的自定义分隔符。
expand 和 unexpand
第 3 页(共8 页)
实用程序 expand 和 unexpand 分别将制表符转换为空格和把空格转换为制表符。制表符被认为等价于特定数量的列,默认是八个列,因此对应于一个制表符的明确空格数目取决于那些空格或制表符出现在何处。除非指定 -a 选项,否则 unexpand 仅把初始的空格转换为制表符(这种默认设置对于重新编排源代码很有用)。
继续前面 employees 文件的例子,我们可以执行一些替换。注意在运行 unexpand 之后,输出中的制表符后面可能跟着一些空格,以便产生所需要的整体对齐。
- $ cat -T employees # show tabs explicitly
- Alice Aaronson^ISystem Administrator^I99 9th Street
- Bob Babuk^IProgrammer^I7 77th Avenue
- Carol Cavo^IManager^I111 West 1st Blvd.
- $ expand -25 employees
- Alice Aaronson System Administrator 99 9th Street
- Bob Babuk Programmer 7 77th Avenue
- Carol Cavo Manager 111 West 1st Blvd.
- $ expand -25 employees | unexpand -a | hexdump -n 50 -c
- 0000000 A l i c e A a r o n s o n \t \t
- 0000010 S y s t e m A d m i n i s t
- 0000020 r a t o r \t 9 9 9 t h S
- 0000030 t r
- 0000032
复制代码
fold
第 4 页(共8 页)
fold 实用程序简单地迫使文件中的行换行。默认情况下,换行是从第 80 列之后开始,不过您可以指定其他宽度。fold 只具有有限种类的自动换行格式,但是它不会完全重新换行段落。 选项 -s 对于至少迫使在空白处换行是很有用的。下面使用我最近的一篇文章作为资料来源(使用我们前面看到的工具来剪取一个例子):
- $ tail -4 rexx.txt | cut -c 3-
- David Mertz' fondness for IBM dates back embarrassingly many decades.
- David may be reached at [email]mertz@gnosis.cx[/email]; his life pored over at
- [url]http://gnosis.cx/publish/.[/url] And buy his book: _Text Processing in
- Python_ ([url]http://gnosis.cx/TPiP/[/url]).
- $ tail -4 rexx.txt | cut -c 3- | fold -w 50
- David Mertz' fondness for IBM dates back embarrass
- ingly many decades.
- David may be reached at [email]mertz@gnosis.cx[/email]; his life
- pored over at
- [url]http://gnosis.cx/publish/.[/url] And buy his book: _Text
- Processing in
- Python_ ([url]http://gnosis.cx/TPiP/[/url]).
- $ tail -4 rexx.txt | cut -c 3- | fold -w 50 -s
- David Mertz' fondness for IBM dates back
- embarrassingly many decades.
- David may be reached at [email]mertz@gnosis.cx[/email]; his life
- pored over at
- [url]http://gnosis.cx/publish/.[/url] And buy his book:
- _Text Processing in
- Python_ ([url]http://gnosis.cx/TPiP/[/url]).
复制代码
fmt
第 5 页(共8 页)
对于大多数用途来说,fmt 是比 fold 更有用的换行工具。实用程序 fmt 不仅换行,而且同时保留初始的缩进,并聚合行以实现段落对齐(视需要而定)。在传输或最终存储之前,fmt 对于格式化诸如电子邮件消息之类的文档很有用。
- $ tail -4 rexx.txt | fmt -40 -w50 # goal 40, max 50
- David Mertz' fondness for IBM dates back
- embarrassingly many decades. David may be
- reached at [email]mertz@gnosis.cx[/email]; his life pored
- over at [url]http://gnosis.cx/publish/.[/url] And
- buy his book: _Text Processing in Python_
- ([url]http://gnosis.cx/TPiP/[/url]).
- $ tail -4 rexx.txt | fold -40
- David Mertz' fondness for IBM dates ba
- ck embarrassingly many decades.
- David may be reached at mertz@gnosis.c
- x; his life pored over at
- [url]http://gnosis.cx/publish/.[/url] And buy his
- book: _Text Processing in
- Python_ ([url]http://gnosis.cx/TPiP/[/url]).
-
复制代码
GNU 版本的 fmt 提供了几种用于首行和后续行缩进的选项。其中一个有用的选项是 -u,它规格化字间距和行间距(多余的空白将被删除)。
nl (和 cat)
第 6 页(共8 页)
实用程序 nl 对文件中的行编号,并具有决定编号如何出现的各种选项。cat 包含您需要用于大多数目的的行编号选项――在 cat 满足您需要的时候请选择这个更通用的工具。只有在诸如控制前导零的显示这样的特殊情况下,才需要使用 nl(由于历史的原因,cat 并不总是包括行编号)。
- $ nl -w4 -nrz -ba rexx.txt | head -6 # width 4, zero padded
- 0001 LINUX ZONE FEATURE: Regina and NetRexx
- 0002 Scripting with Free Software Rexx implementations
- 0003
- 0004 David Mertz, Ph.D.
- 0005 Text Processor, Gnosis Software, Inc.
- 0006 January, 2004
- $ cat -b rexx.txt | head -6 # don't number bare lines
- 1 LINUX ZONE FEATURE: Regina and NetRexx
- 2 Scripting with Free Software Rexx implementations
- 3 David Mertz, Ph.D.
- 4 Text Processor, Gnosis Software, Inc.
- 5 January, 2004
-
复制代码
除了根据编号来讨论行更容易之外,行号还潜在地为下游进程提供排序和过滤规则。
tr
第 7 页(共8 页)
实用程序 tr 是一个用于转换出现在某个文件中的字符的强有力工具――或转换 STDIN 中出现的字符,因为 tr 独占式地操作 STDIN ,并独占式地写到 STDOUT(当然允许重定向和管道)。
tr 具有比他的兄长 sed 更有限的功能,后者没有包括在文本实用程序中(本教程也不讨论它),但是仍然在类 UNIX 系统上几乎总是可用。虽然 sed 能够执行正则表达式的通用替换,但是 tr 仅限于替换和删除单个字符(它没有真正的上下文概念)。归根结底,tr 使用目标字符串中的字符来替换那些包含在源字符串中的 STDIN 字符。
一个简单的例子有助于说明 tr 的用法。我们可能有这样一个文件,其中的制表符和空格数量不定,我们希望规格化那些分隔符,并且使用新的分隔符来替换它们。这里的技巧是使用 -s(squeeze,压缩)标记来消除相同的连续字符序列:
- $ expand -26 employees | unexpand -a > empl.multitab
- $ cat -T empl.multitab
- Alice Aaronson^I^I System Administrator^I 99 9th Street
- Bob Babuk^I^I Programmer^I^I 7 77th Avenue
- Carol Cavo^I^I Manager^I^I 111 West 1st Blvd.
- $ tr -s "\t " "| " < empl.multitab | /usr/local/bin/cat -T
- Alice Aaronson| System Administrator| 99 9th Street
- Bob Babuk| Programmer| 7 77th Avenue
- Carol Cavo| Manager| 111 West 1st Blvd.
-
复制代码
tr,续
第 8 页(共8 页)
除了显式地转换所列出的字符之外,tr 还支持范围和几种指定的字符类别。例如,为了将小写字符转换为大写字符,您可以使用下面的任一种方法:
- $ tr "a-z" "A-Z" < employees
- ALICE AARONSON SYSTEM ADMINISTRATOR 99 9TH STREET
- BOB BABUK PROGRAMMER 7 77TH AVENUE
- CAROL CAVO MANAGER 111 WEST 1ST BLVD.
-
复制代码
- $ tr [:lower:] [:upper:] < employees
- ALICE AARONSON SYSTEM ADMINISTRATOR 99 9TH STREET
- BOB BABUK PROGRAMMER 7 77TH AVENUE
- CAROL CAVO MANAGER 111 WEST 1ST BLVD.
-
复制代码
如果第二个范围与第一个不一样长,第二个将使用其最后一个字符来填补:
- $ tr [:upper:] "a-l#" < employees
- alice aaronson #ystem administrator 99 9th #treet
- bob babuk #rogrammer 7 77th avenue
- carol cavo #anager 111 #est 1st blvd.
-
复制代码
这里,该脚本使用"#"字符来替换字母表后半部分中的所有大写字母。
您也可以删除 STDIN 流中的字符。您通常可以删除诸如换页之类的特殊字符或者您想要过滤掉的高位字符。不过对于这里的讨论来说,我们还是继续前一个例子:
- $ tr -d [:lower:] < employees
- A A S A 99 9 S
- B B P 7 77 A
- C C M 111 W 1 B.
-
复制代码 |
|