Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 连接文本文件,用新行分隔它们_Database_Bash_Text_Concatenation_Text Files - Fatal编程技术网

Database 连接文本文件,用新行分隔它们

Database 连接文本文件,用新行分隔它们,database,bash,text,concatenation,text-files,Database,Bash,Text,Concatenation,Text Files,我在一个目录中有100多个文本文件,作为一个简单的数据库,每行包含一条记录。总的来说,这些文件的总容量约为25GB。但是,这些记录不是按字母顺序排序的,而且有许多重复项,因此为了使用sort-u之类的方法按字母顺序排列所有~100个文本文件的内容,我首先尝试将所有这些文件合并成一个大文本文件。一个简单的cat是不合适的,因为100个文本文件的开头和结尾不包含新行,据我所知,这将导致文件中的最后一条记录与下一个文件的第一条记录合并 有哪些解决方案可以让我连接文本文件,同时确保有一个新行字符分隔它们

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


有哪些解决方案可以让我连接文本文件,同时确保有一个新行字符分隔它们?我会告诉您通过连接所有输入文件并在中间插入新行来创建该文件:

out=newfile.txt
rm -f "$out"
for f in *.txt
do
    cat "$f" >> "$out"
    echo >> "$out"
done
现在你可以把它分类了。或者删除空行,以防您认为某个输入文件末尾可能有新行。

您可以使用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脚本,这意味着打印所有记录

sort -u *.db > uniquified # adjust glob as needed
我们应该这样做;如有必要,排序将在文件之间插入换行符

cat *.db | sort -u
这是一个经典的问题,缺少尾随换行符的文件出现故障并不是唯一的问题

话虽如此,25GB可能不适合您的RAM,所以sort最终还是会创建临时文件。将文件分为四到五组进行排序,然后合并结果可能会更快。这可以更好地利用大量的重复项。但我只会在简单的命令真的需要很长时间的情况下进行实验

即便如此,单独排序文件可能更慢;通常,最好的办法是为每次排序调用最大化内存资源。例如,您可以使用带有-n选项的xargs将文件列表拆分为每组几十个文件的组。一旦对每个组进行了排序,就可以使用sort-m合并已排序的临时表

关于如何提高分拣速度的几点注意事项:

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

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

在进行排序时,通过关闭交换,避免过度交换导致机器停机:

sudo swapoff -a
你可以在事后再打开它,尽管我个人一直这样运行我的机器,因为它避免在记忆压力下陷入完全无反应状态

理想的方法是调整-S,以便排序使用尽可能多的内存,并通过在适合该内存量的块中排序来避免使用内部临时变量。合并已排序的块比排序快得多,而且它不需要额外的磁盘空间就可以按顺序读写。您可能需要做一些实验来找到一个好的块大小

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

当然,也就是说,假设您的猫可以处理不以换行符结尾的文件

对于*.txt中的i;做echo>>$i;完成;cat*.txt | sort-u>newfile?只需在sort命令行中列出多个文件的名称,即可对其进行排序。不需要连接。@rici会将它们的内容相互排序吗?因此,如果文件1碰巧包含以a开头的所有条目,文件2将继续以b开头的条目?输出是所有输入行的排序;它不会独立地对文件进行排序。这是一种输入的串联,除了每个输入文件都被视为正确终止。我相信这正是您要寻找的行为。我完全不知道/忘记了排序可以用于从已排序的内容创建输出文件,我只是假设它在内部对提供给它的输入文件的内容进行排序。因此,从本质上讲,您的意思是,在包含文本文件的目录中执行sort-u*>newfile.txt将满足我的所有条件?我昨天决定选择此解决方案,因为它是最简单的。我使用sort-u*-s70%>finished.txt。它运行了至少6个小时,然后我让它运行了一整晚,醒来后发现它终止了,出现了以下错误:sort:write failed:/tmp/sortJZDIUm:设备上没有剩余空间。尽管我有
e安装/tmp的驱动器上有16GB的RAM和17GB的空闲空间。从这一点上看,你有什么建议?@Hashim:分解成块并合并结果可能更快的原因是uniqify步骤在最后完成了。这也是临时空间不足的原因。因此,如果进行拆分和合并,最终合并操作的数据将更少。此外,merge不需要排序。排序在日志n上;合并已启用。但是合并速度更快的主要原因是它读取和写入顺序记录,这也是文件系统优化的目的。@Hashim:最后一个命令是sort-mu partial?.txt;您仍然需要在不同的块之间统一行。哈希姆:听起来像个计划。将块设置为可用内存的大小,这样排序就不需要创建临时文件。考虑到你正在使用的其他东西正在使用多少内存;在顶部进行一些试验会给你一个很好的操控感。正如我所说的,当你这样做的时候关闭交换将保护你。@Hashim:祝你好运。我把这些评论写进了答案中,这样它们就会持续下去。