0

0

如何在Linux中去除重复行 Linux uniq相邻去重实战

P粉602998670

P粉602998670

发布时间:2025-09-08 11:23:01

|

353人浏览过

|

来源于php中文网

原创

答案:在Linux中去除重复行最有效的方法是结合sort和uniq命令。由于uniq只能去除相邻的重复行,因此必须先使用sort命令将相同内容的行聚集在一起。例如,执行sort data.txt | uniq可实现完整去重,等效的简洁写法为sort -u data.txt。此外,uniq支持多种参数扩展功能:-c统计行出现次数,-d仅显示重复行,-u仅显示唯一行,-i忽略大小写,-f跳过前N个字段,-s跳过前N个字符。对于大文件,可通过sort -S指定内存缓冲区或-T指定临时目录优化性能。超大规模数据建议使用Spark、Hadoop或数据库的DISTINCT功能。

如何在linux中去除重复行 linux uniq相邻去重实战

在Linux中去除重复行,最核心且常用的工具

uniq
命令。不过,单独使用
uniq
往往不够,因为它只处理“相邻”的重复行。所以,真正的实战中,你几乎总是会把它和
sort
命令结合起来使用,先排序让所有相同的行聚在一起,然后再交给
uniq
去重。这就像是先整理好一堆乱七八糟的纸张,再把重复的挑出来。

解决方案

要高效地在Linux中去除文件中的重复行,最经典的组合拳就是

sort
uniq

假设你有一个名为

data.txt
的文件,内容如下:

apple
banana
apple
orange
banana
grape

基本去重:

如果你直接对

data.txt
使用
uniq data.txt
,你会发现它并不能完全去除所有重复的行,因为它只会去除连续出现的重复行。比如,上面的文件,
uniq
处理后可能还是:

apple
banana
apple
orange
banana
grape

这是因为第一个

apple
和第二个
apple
之间隔着一个
banana
,它们不相邻。

所以,正确的做法是先用

sort
命令将文件内容排序,让所有相同的行都紧挨着,然后再通过管道符
|
将排序后的结果传递给
uniq

sort data.txt | uniq

执行这个命令后,输出会是:

apple
banana
grape
orange

这就达到了我们想要的效果。

如果你想直接将去重后的结果保存到新文件,可以这样:

sort data.txt | uniq > unique_data.txt

一个更简洁的技巧:

其实,

sort
命令本身就有一个
-u
(或
--unique
)选项,可以直接在排序的同时去除重复行,省去了再接
uniq
的步骤。我个人平时更喜欢用这个,因为它更直观,少敲一个命令。

sort -u data.txt

这个命令会得到和

sort data.txt | uniq
完全一样的结果。选择哪个,看个人习惯和场景吧。有时为了展示每一步,我会分开写
sort | uniq
,但实际操作中
sort -u
效率上没啥区别,而且更简洁。

uniq
到底是怎么工作的?它和
sort
有什么关系?

说实话,第一次接触

uniq
的时候,我也曾疑惑它为什么不直接把所有重复的都去了。后来才明白,它的设计哲学其实很简单:只关注“当下”和“过去”。具体来说,
uniq
命令在处理输入时,会逐行读取,并且只会将当前行与它紧邻的前一行进行比较。如果这两行内容完全相同,那么当前行就会被丢弃;如果不同,当前行就会被输出。

这就是为什么我前面强调它只能处理“相邻”重复行的原因。举个例子,如果你的文件是这样:

cat
dog
cat
cat
bird

当你直接

uniq
它时,输出会是:

cat
dog
cat
bird

你看,第二个

cat
和第三个
cat
是相邻的,所以第三个
cat
被去掉了。但第一个
cat
和第二个
cat
之间隔着
dog
,它们不相邻,所以
uniq
不会认为第二个
cat
是第一个
cat
的重复。

人民网AIGC-X
人民网AIGC-X

国内科研机构联合推出的AI生成内容检测工具

下载

这就是

sort
登场的原因了。
sort
命令的任务就是把文件中的所有行按照一定的规则(默认是字典序)进行排列。当所有相同的行都被
sort
安排得紧紧挨在一起时,
uniq
的工作就变得异常简单和高效了。它只需要机械地检查相邻行,就能完美地完成去重任务。可以说,
sort
uniq
创造了理想的工作环境。它们俩简直就是天作之合,一个负责整理,一个负责清理。

除了简单去重,
uniq
还能做些什么?常见参数解析

uniq
命令可不是个“傻大个”,它还有一些很实用的参数,能让它在数据分析中发挥更大的作用。这些参数能帮助我们不仅仅是去重,还能统计、筛选。

  • -c
    (count):统计重复行出现的次数 这个参数我用得特别多。它会在每行前面加上该行出现的次数。这对于分析数据中哪些项出现频率最高非常有用。

    sort data.txt | uniq -c

    对于

    data.txt
    (apple, banana, apple, orange, banana, grape),输出会是:

          2 apple
          2 banana
          1 grape
          1 orange

    可以看到,

    apple
    banana
    各出现了两次。

  • -d
    (duplicated):只显示重复的行 如果你只想知道哪些行是重复的(并且只显示一次),而不是所有唯一的行,
    -d
    就派上用场了。

    sort data.txt | uniq -d

    输出:

    apple
    banana

    它只会列出那些在原始文件中出现过多次的行,每行只显示一次。

  • -u
    (unique):只显示不重复的行
    -d
    相反,
    -u
    会只显示那些在文件中只出现过一次的行。

    sort data.txt | uniq -u

    输出:

    grape
    orange

    这对于找出文件中真正的“独一份”数据很有帮助。

  • -i
    (ignore-case):忽略大小写 在比较行时,忽略字母的大小写。这在处理用户输入或不规范数据时非常实用。

    # 假设文件内容有 Apple 和 apple
    sort -f data.txt | uniq -i

    注意,这里

    sort
    也用了
    -f
    来进行大小写不敏感的排序,否则
    uniq -i
    可能会因为排序问题而漏掉一些去重。

  • -f N
    (skip-fields):跳过前N个字段 这个参数在处理结构化数据时非常强大。它会忽略每行的前 N 个字段进行比较。字段默认由空格分隔。

    # 假设文件内容是:
    # 2023-01-01 apple
    # 2023-01-02 banana
    # 2023-01-03 apple
    # 2023-01-04 banana
    sort -k 2,2 file_with_dates.txt | uniq -f 1

    这里

    sort -k 2,2
    是按第二个字段排序,然后
    uniq -f 1
    忽略第一个字段(日期)进行去重。

  • -s N
    (skip-chars):跳过前N个字符
    -f
    类似,但它是跳过前 N 个字符,而不是字段。

    # 假设文件内容是:
    # ID12345_dataA
    # ID12345_dataB
    # ID67890_dataA
    sort file.txt | uniq -s 6 # 忽略前6个字符("ID12345_")

    这在处理有固定前缀但后缀不同的数据时很有用。

这些参数的组合使用,能让

uniq
变得非常灵活,远不止简单的去重那么单调。

遇到大文件去重,性能和内存是挑战吗?有没有更高效的办法?

当处理非常大的文件,比如几十GB甚至TB级别的文件时,

sort | uniq
组合确实会面临一些挑战。这主要是因为
sort
命令在处理大文件时,如果文件内容无法完全加载到内存中,它会使用磁盘作为临时存储空间(所谓的“外部排序”)。这意味着大量的磁盘I/O操作,这会显著降低处理速度。此外,如果你的系统内存不足,
sort
可能会频繁地在内存和磁盘之间交换数据,进一步拖慢速度。CPU的负担也会相应增加。

所以,对于超大文件,我们确实需要考虑一些更高效或者说更适合大规模数据处理的策略:

  1. 优化

    sort
    命令本身:

    • 增加内存缓冲区:
      sort
      有一个
      -S
      参数可以指定排序时使用的内存大小。例如
      sort -S 2G file.txt | uniq
      会告诉
      sort
      使用2GB内存进行排序。如果你的系统有足够的空闲内存,适当增加这个值可以减少磁盘I/O。
    • 指定临时目录:
      sort
      默认在
      /tmp
      目录创建临时文件。如果
      /tmp
      目录所在的磁盘速度较慢,或者空间不足,你可以通过
      -T
      参数指定一个更快、空间更大的临时目录,比如
      sort -T /mnt/ssd_temp -u large_file.txt
  2. 分块处理(如果可行): 如果你的数据可以逻辑上分成多个独立的部分,并且去重可以在每个部分内独立进行,最后再合并去重,那么可以考虑分块处理。但这通常比较复杂,需要自定义脚本来管理。对于通用的去重场景,这不常见。

  3. 使用专门的大数据工具: 对于真正意义上的“大数据”,比如TB级别的文件,传统的命令行工具可能会力不从心。这时候,更专业的工具或平台会是更好的选择:

    • Apache Spark/Hadoop: 这些分布式计算框架天生就是为处理大规模数据而设计的。它们可以将数据分散到多台机器上并行处理,去重只是它们众多功能中的一个。如果你已经在使用这些平台,那么使用它们内置的去重功能(如Spark RDD/DataFrame的
      distinct()
      方法)会比在单机上折腾
      sort | uniq
      高效得多。
    • 数据库系统: 如果数据最终要存储在数据库中,那么直接将数据导入数据库(比如PostgreSQL, MySQL, MongoDB等),然后利用SQL的
      DISTINCT
      关键字或者创建唯一索引来去重,也是一个非常高效且可靠的方法。
  4. 哈希表/Bloom Filter(针对特定场景): 对于某些场景,如果你只需要知道某个元素是否“可能”存在,或者可以容忍极低的误判率,那么可以考虑使用Bloom Filter。它是一种空间效率很高的数据结构,可以快速判断一个元素是否在集合中。但它不能提供精确的去重,也无法直接输出去重后的文件。这更多是理论上的优化,实际命令行操作中很少直接用到。

总的来说,对于大多数日常工作和文件大小在几GB到几十GB的范围,

sort -u
或者
sort | uniq
配合适当的内存和临时目录优化,仍然是Linux下最简单、最直接且相当高效的去重方案。只有当文件规模达到“大数据”级别,并且单机性能成为瓶颈时,才需要考虑更复杂的分布式解决方案。别小看这些命令行工具,它们在设计上其实考虑到了很多性能问题,远比我们想象的要健壮。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

676

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

346

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1095

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

357

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

675

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

571

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

414

2024.04.29

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.1万人学习

Git 教程
Git 教程

共21课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号