首页 > 解决方案 > 连接文本文件,用新行分隔它们

问题描述

我在一个目录中只有 100 多个文本文件,用作一个简单的数据库,每行包含一条记录。这些文件总共加起来大约 25GB。但是,记录没有按字母顺序排序,并且有很多重复项,因此为了使用类似的内容对所有约 100 个文本文件的内容按字母顺序排列sort -u,我首先尝试将所有这些文件组合成一个大文本文件。简单cat是不合适的,因为 100 个文本文件的开头和结尾不包含新行,这(据我的理解)会导致文件中的最后一条记录与下一个文件的第一条记录合并。

有什么解决方案可以让我连接我的文本文件,同时确保有一个换行符分隔它们?

标签: databasebashtextconcatenationtext-files

解决方案


一个简单的

sort -u *.db > uniquified # adjust glob as needed

应该这样做;sort如有必要,将在文件之间插入换行符。

cat *.db | sort -u

是一个经典的UUoC,文件缺少尾随换行符的故障并不是唯一的问题。

话虽如此,25GB 可能不适合您的 RAM,因此sort无论如何最终都会创建临时文件。将文件分成四五组,然后合并结果可能会更快。这可以更好地利用大量重复。但我只会在简单命令确实需要大量时间的情况下进行试验。

即便如此,单独对文件进行排序可能会更慢;通常最好的办法是在每次调用sort. 例如,您可以使用xargs选项-n将文件列表拆分为每组几十个文件。对每个组进行排序后,您可以使用它sort -m来合并排序的临时对象。

关于如何提高分拣速度的几点说明:

  1. LC_COLLATE=C sort如果您不需要对字母数据进行区域感知排序,请使用。这通常会使排序速度提高三到四倍。

  2. 避免使用 RAM 磁盘作为临时空间。(在许多 Linux 发行版中,/tmp是 RAM 磁盘。)由于sort在 RAM 用完时使用临时磁盘,因此将临时磁盘放入 RAM 磁盘会适得其反。出于同样的原因,不要将自己的临时输出文件放在/tmp. /var/tmp应该是真盘;更好的是,如果可能的话,使用第二个磁盘驱动器(当然不是慢速 USB 驱动器)。

  3. 通过关闭交换,避免在进行排序时因过度交换而拖累机器:

    sudo swapoff -a
    

    您可以在之后重新打开它,尽管我个人一直都这样运行我的机器,因为它避免了在内存压力下陷入完全无响应的状态。

  4. 理想的做法是进行调整-S,以便sort使用尽可能多的内存,并通过对适合该内存量的块进行排序来避免使用内部临时文件。(合并已排序的块比排序快得多,它按顺序读取和写入,而不需要额外的磁盘空间。)您可能需要做一些实验才能找到合适的块大小。


推荐阅读