根据第三列排序


130

我面临着一个巨大的4列文件。我想根据其第三列在stdout中显示排序后的文件:

cat myFile | sort -u -k3

这足以执行技巧吗?


4
请注意,您可以将其写为sort -u -k3 < myFile
Gerrit

6
作为sort -u -k3 myFile,甚至
塞巴斯蒂安·格拉夫

Answers:


165
sort -k 3,3 myFile

会根据当前语言环境定义的排序顺序,假设这些列由空格序列(在POSIX / C语言环境中为ASCII SPC和TAB字符)分隔,则将显示按第三列排序的文件。

请注意,该列中包含前导空格(默认分隔符是从非空格到空格的过渡),这可以在不忽略空格以进行比较的语言环境中有所作为,请使用-b选项忽略领先的空白。

请注意,它完全独立于外壳程序(所有外壳程序都将以相同的方式解析该命令行,外壳程序通常没有sort内置命令)。

-k 3是进行排序开始于3线的部分RD柱(包括前导空白)。在C语言环境中,由于空格和制表符位于所有可打印字符之前,因此通常获得的结果与-k 3,3(与具有相同第三字段的行除外)相同,

-u如果有几行相同的排序(即排序键对相同的行进行排序(不一定等于equal)),则仅保留其中一行。

cat是命令CON enate。您在这里不需要它。

如果列之间用其他-t分隔符,则需要使用选项来指定分隔符。

给定示例文件 a

$ cat a
a c c c
a b ca d
a b  c e
a b c d

-u -k 3

$ echo $LANG
en_GB.UTF-8

$ sort -u -k 3 a
a b ca d
a c c c
a b c d
a b  c e

第2行和第3行具有相同的第三列,但此处的排序键是从第三列到行尾,因此-u保留两者。␠ca␠d各种各样之前␠c␠c因为空间第一遍忽略了我的语言环境,cad之前排序cc

$ sort -u -k 3,3 a
a b c d
a b  c e
a b ca d

对于第3列为的那些,上面仅保留一个␠c。请注意如何␠␠c保留带有(2个前导空格)的那个。

$ sort -k 3 a
a b ca d
a c c c
a b c d
a b  c e
$ sort -k 3,3 a
a b c d
a c c c
a b  c e
a b ca d

查看a b c d和的顺序如何a c c c颠倒。在第一种情况下,由于␠c␠c各种之前␠c␠d,在第二种情况下,因为排序关键字是相同的(␠c),最后的手段比较该线全放比较a b c d之前a c c c

$ sort -b -k 3,3 a
a b c d
a b  c e
a c c c
a b ca d

一旦我们忽略了空格,前三行的排序键是相同的(c),因此它们通过最后的比较进行排序。

$ LC_ALL=C sort -k 3 a
a b  c e
a c c c
a b c d
a b ca d
$ LC_ALL=C sort -k 3,3 a
a b  c e
a b c d
a c c c
a b ca d

在C语言环境中,␠␠c排序是在之前进行的,␠c因为那里只有一遍,字符(然后是单个字节)根据其代码点值(其中空间的代码点比更低)进行排序c


列以- blank分隔,除了空格和制表符外,还可能包括其他字符(取决于语言环境)。
jfs

1
不错,+ 1。你能解释一下3,3吗?为什么不只是3呢?
terdon

@terdon,请参阅带有示例的扩展说明。
斯特凡Chazelas

@JFSebastian,您是对的,答案已更新。
斯特凡Chazelas

嗯,要使其仅在第3位排序,而不是其余部分,谢谢。
terdon

4

如果您理解文本文件(第4个字符)中的“列”,则可以,您的解决方案应该可以工作(甚至sort -u -k3 myFile允许sort通过随机访问执行一些节省内存的魔术)。如果您理解数据库中的“列”-整个数据实体,后跟一个分隔符,以及可变的列宽,则将需要一些奇特的方法,例如,按大小对ls -l进行排序

      ls -l |awk '{print $5 " " $0;}'| sort -n | cut -d " " -f 2-

(这等效于琐碎的事,ls -lS但很好地举例说明了这一点。)


5
不,默认情况下,排序以空格分隔,不是字符列,要在第三个字符列上进行排序,语法为:sort -k 1.3,1.3ls -l | sort -k5,5n按大小排序。
斯特凡Chazelas

awk解决方案正是我所需要的
jchook

2
sort -g -k column_number 

是使用特定列对具有数字字符的任何列表进行排序的正确命令


1
使用-k已经很好地介绍过了,因此如果您解释了此命令的不同之处或更好之处将很有帮助。也许您还可以包括实际的列号,以解决OP的实际问题。
杰夫·谢勒

这使我可以使用手册页:p“ -g,--general-numeric-sort,根据常规数值进行比较”,这是我需要的。
joels


0
$ sort -k 1.3,1.3 myfile

如果您的文件没有分隔符,将在第三列对myfile文件进行排序。

$ cat myfile 
ax5aa 
aa3ya 
fg7ds 
pp0dd 
aa1bb

$ sort -k 1.3,1.3 myfile 
pp0dd 
aa1bb
aa3ya 
ax5aa 
fg7ds 

手册页类型:

[...] -k,--key = POS1 [,POS2]在POS1(起源1)处开始一个密钥,在POS2(行的默认末尾)处结束它。[...] POS是F [.C] [ OPTS],其中F是字段编号,C是字段中的字符位置;两者都是起源1。如果-t和-b均无效,则将从前一个空格的开头开始计算字段中的字符。OPTS是一个或多个单字母排序选项,它会覆盖该键的全局排序选项。如果没有给出密钥,则使用整行作为密钥。

使用--key = 1.3,1.3时,您说只有一个字段(整行),并且您正在比较此字段的第三个字符位置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.