设为首页收藏本站

IT联盟

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6752|回复: 5

[学习笔记] Linux下sort、uniq、join命令详解

[复制链接]

232

主题

242

帖子

3605

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3605

管理员最佳新人活跃会员热心会员推广达人灌水之王突出贡献优秀版主荣誉管理论坛元老

发表于 2016-12-22 11:59:21 | 显示全部楼层 |阅读模式
sort 命令
同文本文件打交道时,总避不开排序,那是因为对于文本处理任务而言,排序(sort)可以起到不小的作用。sort 命令能够帮助我们对文本文件和 stdin 进行排序操作。通常,它会结合其他命令来生成所需要的输出。
命令格式:
sort [选项] [文件名]
常用参数:
参数 描述
  • -n 基于字符串的长度来排序,使用此选项允许根据数字值排序,而不是字- 母值
  • -k 指定排序关键字
  • -b 默认情况下,对整行进行排序,从每行的第一个字符开始。这个选项导致 sort 程序忽略每行开头的空格,从第一个非空白字符开始排序
  • -m 只合并多个输入文件
  • -r 按相反顺序排序,结果按照降序排列,而不是升序
  • -t 自定义分隔符,默认为制表符
常用范例:
例一:列出/usr/share/目录下使用空间最多的前 10 个目录文件,可以使用如下命令:
du -s /usr/share/* | sort -nr | head -10
du -s /usr/share/* 命令显示/usr/share/目录下所有文件和目录的磁盘使用空间,目录包含目录下的子目录和文件
例二:ls 命令能显示目录下文件的详细信息,包含空间使用大小,但与 du 命令不同的是,ls 命令不计算目录下的子目录和文件的大小。ls 显示格式如下:
-rwxrwxrwx 1 root root 542 11 月 29 test.php
现在想要对 ls 命令输出信息中的空间使用大小字段进行排序,可以使用如下命令:
ls -l /usr/bin/ | sort -nr -k 5 | head -10
例三:首先来看下下面的例子: img 由于 11 由 1 开始,比 5 大,所以排在 5 的前面。这时排序可以通过自定义排序字段来排序。使用下面的命令就可以解决。
sort -k 1,1 -k 2n data.txt
第一个-k 选项指明只对第一个字段排序,1,1 意味着“始于并且结束于第一个字段”。 第二个-k 选项 2n 表示对第二个字段按数值排序。 还有一种格式,如-k 3.4,表示始于第三个字段的第四个字符,按数值排序。
-k 选项的语法格式如下:
[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
这个语法格式可以被其中的逗号(“,”)分为两大部分,Start 部分和 End 部分。
先给你灌输一个思想,那就是“如果不设定 End 部分,那么就认为 End 被设定为行尾”。这个概念很重要的,但往往你不会重视它。
Start 部分也由三部分组成,其中的 Modifier 部分就是类似 n 和 r 的选项部分。我们重点说说 Start 部分的 FStart 和 CStart。 FStart.CStart,其中 FStart 就是表示使用的域,而 CStart 则表示在 FStart 域中从第几个字符开始算“排序首字符”。CStart 是可以省略的,省略的话就表示从本域的开头部分开始。之前例子中的-k 5 就是省略了 CStart 的例子。
同理,在 End 部分中,你可以设定 FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将 CEnd 设定为 0(零),也是表示结尾到“域尾”。
uniq 命令
  • uniq 命令经常和 sort 命令结合在一起使用。uniq 从标准输入或单个文件名参数接受数据有序列表,默认情况下,从数据列表中删除任何重复行。
  • uniq 只能用于排过序的数据输入,因此,uniq 要么使用管道,要么将排过序的文件作为输入,并总是以这种方式与 sort 命令结合起来使用。
  • uniq 命令是 unique 的缩写。

命令格式:
uniq [选项] [文件名]
常用参数:
参数 描述
  • -c 在每行前加上表示相应行目出现次数的前缀编号
  • -d 只输出重复的行
  • -u 只显示唯一的行
  • -D 显示所有重复的行
  • -f 比较时跳过前 n 列
  • -i 在比较的时候不区分大小写
  • -s 比较时跳过前 n 个字符
  • -w 对每行第 n 个字符以后的内容不作对照
常用范例:
例一:找出/bin 目录和/usr/bin 目录下所有相同的命令,可以使用如下命令:
ls /bin /usr/bin | sort | uniq -d
例二:现有文件内容如下,红色方框里的内容表示区号,现在要统计出各个区号的总人数。
实现思路:首先按区号对每行信息排序,然后使用 uniq 命令对区号进行重复行统计。使用命令如下:
sort -k 4.1n,4.1n student.txt | uniq -c -f 3 -w 2
  • sort -k 4.1n,4.1n 表示对第四个字段的第一个字符按数值排序。
  • uniq -c -f 3 -w 2 中-f 3 表示跳过前三列的比较,那么现在只剩下最后一列,-w 2 表示第 2 个字符后的内容不做比较,为什么是 2 呢,因为跳过前三列时并没有跳过最后一列前面的空格分隔符,区号前都还有一个空格。

join 命令
join 命令类似于 paste,它会往文件中添加列,但是它使用了独特的方法来完成。一个 join 操作通常与关系型数据库有关联,在关系型数据库中来自多个享有共同关键域的表格的数据结合起来,得到一个期望的结果。这个 join 命令执行相同的操作,它把来自于多个基于共享关键域的文件的数据结合起来。
通俗地说,就是将两个文件中指定栏位相同的行连接起来,即按照两个文件中共同拥有的某一列,将对应的行拼接成一行。
命令格式:
join [选项] 文件 1 文件 2
常用参数:
参数 描述
  • -j FIELD 等同于 -1 FIELD -2 FIELD,-j 指定一个域作为匹配字段
  • -1 FIELD 以 file1 中 FIELD 字段进行匹配
  • -2 FIELD 以 file2 中 FIELD 字段进行匹配
  • -t 自定义分隔符,默认为制表符
常用范例:
例一:将两个文件中的第一个字段作为匹配字段,连接两个文件,可以使用如下命令:
join a.txt b.txt
例二:指定两个文件的第三个字段为匹配字段,连接两个文件,可以使用如下命令:
join -1 3 -2 3 c.txt d.txt
从上面的结果可以看到,一开始对 a.txt 和 b.txt 文件内容执行 join 命令时报错,这是因为 join 命令跟 uniq 命令一样,只能用于排过序的数据。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|IT技术联盟论坛 ( 京ICP备15062632  点击这里给我发消息

GMT+8, 2019-8-17 21:44 , Processed in 0.074619 second(s), 29 queries .

Powered by Discuz! X3.2 Licensed Designed By

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表