比较大文件时,Join 命令不给出输出

比较大文件时,Join 命令不给出输出

在此输入图像描述我有如下 2 个文件,其中一个文件为 20 GB,另一个文件为 MB

file1.txt (100 MB)

6000000
6000001
6000003
file2.txt (20 gb) 

6000000;dgdfgdfgdfgdfgdggeewtwtwtwetewtt
6000003;eryeyyrtuytityiytititityityiytii
6000005;qwrwqrwqrrrrerewrwerewrwrrrewrew

我想要所有匹配的内容和输出,例如:

6000000;dgdfgdfgdfgdfgdggeewtwtwtwetewtt
6000003;eryeyyrtuytityiytititityityiytii

现在,我对这两个文件使用了排序命令,并在下面使用了连接命令,但我没有得到任何输出?请帮忙这里出了什么问题?

join -t';' file1.txt file2.txt >> file3.txt

答案1

正如其他人已经提到的,您的第一个文件必须事先转换为 unix 行结尾。但是,您不需要更改文件本身。相反,您可以尝试即时转换它。

将命令行更改为以下内容:

join -t';' <(dos2unix file1.txt) file2.txt >> file3.txt

如果两个文件都有 dos 结尾,请使用

join -t';' <(dos2unix file1.txt) <(dos2unix file2.txt) >> file3.txt

答案2

您有 DOS 类型的换行符 ( CRLF),并且join无法理解这些文件。

  • 选项1dos2unix:使用存储库中的文件进行转换。
dos2unix file1.txt file2.txt

请注意,这将改变文件 - 取决于接下来读取它们的程序,您可能需要通过 - 猜猜 - 重新转换结果unix2dos file3.txt

  • 选项2:使用awkwith\r\n作为记录分隔符:
awk ' BEGIN {FS=";" ; RS="\r\n" }
      NR==FNR { marker[$1]=$1 }
      NR!=FNR && $1 in marker ' file1.txt file2.txt

这里的优点是换行符保持完整,并且 20GB 文件仅被读取,而不被处理 - 这对于临时文件的写入来说应该更好。

笔记我假设这两个文件都是 DOS 风格的解决方案awkfile如果涉及“很长的队伍”,并不能真正说明这一点。

答案3

您的文件file1.txt(至少,可能两者)是 DOS 文本文件。当在 Unix 系统上用作文本文件时,DOS 文本文件在每行末尾有一个额外的回车符。

每行末尾的额外回车符会干扰第一个文件中数据的解释,从而join尝试将末尾带有回车符的数据(来自第一个文件)与不包含回车符的数据进行匹配。末尾有回车符(第二个文件的第一个字段)。这意味着没有一对连接键会匹配,并且您不会得到任何输出。

使用诸如之类的工具将文件转换为 Unix 文本文件dos2unix,然后重试您的join命令。

不执行系统管理任务时,还应考虑使用非特权用户帐户而不是根用户帐户。使用 root 帐户执行日常任务是不负责任的,因为它会禁用 Unix 系统通常强制执行的大多数安全措施(例如基本文件和目录权限等)

相关内容