连接文本文件,并用新行分隔

时间:2018-09-09 15:24:48

标签: database bash text concatenation text-files

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

有什么解决方案可以使我串联文本文件,同时确保用单个换行符分隔文本文件?

4 个答案:

答案 0 :(得分:4)

简单

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使用尽可能多的内存,并通过对适合该内存量的块进行排序来避免使用内部临时对象。 (合并排序的块比排序要快得多,并且它可以按顺序读写,而无需额外的磁盘空间。)您可能需要做一些实验才能找到合适的块大小。

答案 1 :(得分:2)

我会告诉您通过串联所有输入文件并在中间插入新行来创建该文件:

out=newfile.txt
rm -f "$out"
for f in *.txt
do
    cat "$f" >> "$out"
    echo >> "$out"
done

现在您可以对其进行排序。或者删除空行,以防万一您可能会有一些输入文件的末尾有一个新行。

答案 2 :(得分:2)

您可以使用awk。

$ od -t x1 file1
0000000 72 65 63 6f 72 64 31 0a 72 65 63 6f 72 64 32
0000017
$ od -t x1 file2
0000000 72 65 63 6f 72 64 31 0a 72 65 63 6f 72 64 32 0a
0000020 72 65 63 6f 72 64 33
0000027
$ awk 1 file1 file2
record1
record2
record1
record2
record3

1在这里是awk脚本,这意味着打印所有记录

答案 3 :(得分:1)

sort *应该是您所需要的,但以防万一您确实需要在文件内容中添加换行符以供后续工具处理,请按以下步骤操作:

$ ls
file1  file2
$ cat file1
foo$
$ cat file2
bar$
$ cat file1 file2
foobar$

$ find . -type f -exec sh -c '(cat {}; printf "\\n")' \;
foo
bar

当然,就是假设您的cat可以处理未以换行符结尾的文件!