免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2430 | 回复: 3
打印 上一主题 下一主题

转贴 技巧:用 sort 和 tsort 对文件进行排序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-03-18 10:49 |只看该作者 |倒序浏览
认识您的文本实用程序

Jacek Artymiak(jacek@artymiak.com)
自由作家和顾问
2003 年 3 月 6 日

通过使用 sort 和 tsort,而不是采取使用 Perl 或 Awk 的较复杂的解决方案,可以节省时间,同时还能避免令人头疼的问题。Jacek Artymiak 将向您说明如何做到这一点。
尽管可以用 Perl 或 Awk 编写高级排序应用程序,但并非总是有此必要,而且这样的工作也常常令人感到头疼。使用 sort 命令,您同样可以实现您所需的大多数功能,而且更容易,它可以对多个文件中的行进行排序、合并文件甚至可以查看是否有必要对它们进行排序。您可以指定排序键(用于比较的行中的一部分),也可不指定,后一种情况下 sort 就比较所有行。

因此,如果您想对密码文件进行排序,就可以使用下列命令(请注意,您不能将输出直接发送到输入文件,因为这会破坏输入文件。这就是为何您需要将它发送到临时文件中,然后将该文件重命名为 /etc/passwd 的原因,如下所示)。

清单 1. 简单排序
$ su -
# sort /etc/passwd > /etc/passwd-new
# mv /etc/passwd-new /etc/passwd
                       



有关 sort 和 tsort 的更多信息
通过打开有关排序操作的 GNU 手册页来学习手册页中的内容,或者通过在命令行中输入 man sort 或 man tsort 在新的终端窗口的手册页或信息页中查看这些选项。
如果您想倒转排序的次序,则应当使用 -r 选项。您还可以用 -u 选项来禁止打印相同的行。

sort 的一个非常实用的特性是它用字段键进行排序的能力。字段是一个文本字符串,通过某个字符与其它字段分隔开。例如,/etc/passwd 中的字段是用冒号(:)分隔的。因此,如果愿意的话,您可以按照用户标识、组标识、注释字段、主目录或 shell 对 /etc/passwd 进行排序。要做到这一点,请使用 -t 选项,其后跟着用作分隔符的字符,接着是用作排序键的字段编号,再跟作为键的最后一个字段的编号;例如,sort -t : -k 5,5 /etc/passwd 按照注释字段对密码文件进行排序,该字段中存储了完整的用户名(如“John Smith”)。而 sort -t : -k 3,4 /etc/passwd 同时使用用户标识和组标识对同一个文件进行排序。如果您省略了第二个数字,那么 sort 会假定键是从给定的字段开始,一直到每一行的末尾。动手试一试,并观察其中的区别(当数字排序看上去有错时,请添加 -g 选项)。

还要注意的是,空白过渡是缺省的分隔符,因此,如果字段已经用空白字符分隔了,那么您可以省略分隔符,只使用 -t(另注:字段的编号是从 1 开始的)。

为了更好地进行控制,您可以使用键和偏移量。偏移量是用点与键相分隔的,比如在 -k 1.3,5.7 中,表示排序键应当从第 1 个字段的第 3 个字符开始,到第 5 个字段的第 7 个字符结束(偏移量也是从 1 开始编号的)。何时会用得着偏移量呢?嗯,我时常用它来对 Apache 日志进行排序;键和偏移量表示法让我跳过了日期字段。

另一个要关注的选项是 -b,它告知 sort 忽略空白字符(空格、跳格等等)并将行中的第一个非空白字符当做是排序键的开始。还有,如果您使用该选项,那么将从第一个非空白字符开始计算偏移量(当字段分隔符不是空白字符,且字段可能包含以空白字符开头的字符串时,这非常有用)。

可以用下面这些选项来进一步修改排序算法:-d(只将字母、数字和空白用作排序键)、-f(关闭大小写区分,认为小写和大写字符是一样的)、-i(忽略非打印的 ASCII 字符)、-M(使用三个字母的月份名称缩写:JAN、FEB、MAR … 来对行进行排序)和 -n(只用数字、- 和逗号或另外一个千位分隔符对行进行排序)。这些选项以及 -b 和 -r 选项可以用作键编号的一部分,在这种情况下,它们只适用于该键而非全局,其作用就跟在键定义外使用它时一样。

以键编号的用法为例,请考虑:

sort -t: -k 4g,4 -k 3gr,3 /etc/passwd

这条命令将按照组标识对 passwd 文件进行排序,而在组内按照用户标识进行逆向排序。

但是这并非 sort 的全部能力。如果您所使用的键不能用来确定哪一行是在先,那么它也可以解决这类平局问题。增加一个解决平局问题的提示,请添加另一个 -k 选项,让它跟在字段和(可选的)偏移量后面,使用与前面用于定义键相同的表示法;例如,sort -k 3.4,4.5 -k 7.3,9.4 /etc/passwd 对行进行排序时,使用从第 3 个键的第 4 个字符开始到第 4 个键的第 5 个字符结束的键,然后再采用从第 7 个字段的第 3 个字符到第 9 个字段的第 4 个字符结束的键来解决上述难题。

最后一组选项处理输入、输出和临时文件。例如,-c 选项,当它用于 sort -c < file 中时,它检查输入文件是否已进行了排序(您也可以使用其它选项),如果已进行了排序,则报告一个错误。这样,在处理可能需要花很长时间进行排序的大型文件之前,可以很方便地对其进行检查。当您将 -u 选项和 -c 选项一起使用时,会被解释为一个请求:检查输入文件中不存在两个相同的行。

当您处理大型文件时还有一个很重要的 -T 选项,它用于为临时文件(这些临时文件在 sort 完成工作之后会被除去)指定其它目录,而不是缺省的 /tmp 目录。

您可以使用 sort 来同时处理多个文件,这样做的方式基本上有两种:首先可以使用 cat 来并置它们,如下所示:

cat file1 file2 file3 | sort > outfile

或者,可以使用下面这个命令:

sort -m file1 file2 file3 > outfile

第二种情况有个条件:在将所有输入文件一起进行 sort -m 之前,每个文件都必须经过排序。这看起来似乎是个不必要的负担,但事实上这加快了工作速度并节约了宝贵的系统资源。对了,别忘了 -m 选项。在这里您可以使用 -u 选项来禁止打印相同的行。

如果需要某种更深奥的排序方法,您可能要查看 tsort 命令,该命令对文件执行拓扑排序。拓扑排序和标准 sort 之间的差别如清单 2 所示(您可以从参考资料下载 happybirthday.txt)。

清单 2. 拓扑排序和标准排序之间的差别$ cat happybirthday.txt

Happy Birthday to You!

Happy Birthday to You!

Happy Birthday Dear Tux!

Happy Birthday to You!

$ sort happybirthday.txt

Happy Birthday Dear Tux!

Happy Birthday to You!

Happy Birthday to You!

Happy Birthday to You!

$ tsort happybirthday.txt

Dear

Happy

to

Tux!

Birthday

You!



当然,对于 tsort 的使用来说,这并非一个非常有用的演示,只是举例说明了这两个命令输出的不同。

tsort 通常用于解决一种逻辑问题,即必须通过观察到的部分次序预测出整个次序;例如(来自 tsort 信息页中):

tsort <<EOF a b c d e f b c d e EOF

会产生这样的输出


      a
      b
      c
      d
      e
      f




有什么问题或意见吗?我希望收到您的来信 - 请将邮件发送到 jacek@artymiak.com。

下一次,我们将深入研究 tr。

参考资料

请下载用于清单 2 的示例文件:happybirthday.txt。


请在 GNU text utilities 手册(位于 MIT 站点的同一目录的展开视图中,您还可以找到众多更加有用的 GNU 工具列表)中找到这些有用工具的更多信息。


Windows 用户可以在 Cygwin 软件包中找到这些工具。


Mac OS X 用户可能想试用 Fink(它在全新的 Mac OS X 下安装了功能丰富的 UNIX 环境)。


您碰到问题了?请查阅 GNU 文本实用程序的常见问题解答。


在深入研究我们在此所讨论的工具之前还需要更多介绍性的信息?您可以尝试从 UNIXhelp for users 入手。


当然,这一领域的经典著作是由 O'Reilly and Associates 出版的 Unix Power Tools(Jerry Peek、Tim O'Reilly 和 Mike Loukides 合著:1997;ISBN 1-56592-260-3)。


别忘了,Jargon 文件中包含了有关排序主题的有趣内容。


请阅读该 developerWorks 系列文章中由 Jacek 撰写的其它技巧文章:
了解 textutils
用 cat 合并文件
使用 head 和 tail 以块方式读取文本流


请在 developerWorks Linux 专区中查找您正在寻找的 Linux 参考资料。

关于作者
Jacek Artymiak 是一位自由顾问、开发人员和作家。自从 1991 年他就一直为 UNIX 和 BSD 操作系统的许多商业性和免费的变体(AIX、HP-UX、IRIX、Solaris、Linux、FreeBSD、NetBSD、OpenBSD 和其它操作系统)以及 MS-DOS、Microsoft Windows、Mac OS 与 Mac OS X 开发软件。Jacek 的专长是商业及金融应用程序开发、Web 设计、网络安全性、计算机图形、动画和多媒体。在技术主题方面,他是一位多产的作家,并与他人一同合著了“Install, Configure, and Customize Slackware Linux”(Prima Tech,2000)和“StarOffice for Linux Bible”(IDG Books,2000)。在 SourceForge 上可以找到 Jacek 的许多软件项目。可以从他的个人网站更多地了解他,并且可以通过 jacek@artymiak.com 与他联系。

http://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/l-tiptex4/index.shtml

论坛徽章:
0
2 [报告]
发表于 2005-09-23 11:06 |只看该作者

转贴 技巧:用 sort 和 tsort 对文件进行排序

谢谢楼主整理,收藏先,再学习!

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
3 [报告]
发表于 2005-09-23 11:54 |只看该作者

转贴 技巧:用 sort 和 tsort 对文件进行排序

IBW DW上的吧~

论坛徽章:
0
4 [报告]
发表于 2005-09-23 18:09 |只看该作者

转贴 技巧:用 sort 和 tsort 对文件进行排序

学习一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP