我有 2 个大型文本文件(每个约 500M,约 15GB),如下所示:
文件P.txt:
[电子邮件保护]:测试一下 [电子邮件保护]:测试测试1 [电子邮件保护]:测试测试2 [电子邮件保护]:测试测试3 [电子邮件保护]:测试测试4
文件E.txt
[email protected]:testtest
[email protected]:testtest0
[email protected]:testtest2
[email protected]:testtest3
[email protected]:testtest5
(请注意FileE.txt
中没有的行FileP.txt
。我不想包含这些行。粗体行是应该以 结尾的行output.txt
,因为它们不在 中FileE.txt
。)
我想运行FileE.txt
并删除在fromFileP.txt
中找到的所有行并输出到新文件中。FileE.txt
FileP.txt
它看起来应该是这样的:
输出.txt:
[电子邮件保护]:测试测试1 [电子邮件保护]:测试测试4
我尝试了一些命令,
这是我的 grep 命令:
$ grep -Fvxf FileE.txt FileP.txt > output.txt
但是,我收到此错误(显然是因为文件太大):
grep: memory exhausted
对于那些感兴趣的人,运行$ ulimit -a
回报:
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
open files (-n) 256
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 2032
cpu time (seconds, -t) unlimited
max user processes (-u) 256
virtual memory (kbytes, -v) unlimited
所以我的问题是,完成这个过程最有效和最简单的方法是什么?
注意:文件未排序。
答案1
如果文件已排序,则执行
comm -23 fileP.txt fileE.txt
comm
比较两个已排序的文件,查找它们有共同点的行。例如,给定这个文件,其中的颜色名称以辅音开头:
blue
green
purple
red
white
yellow
以及名称以元音结尾的颜色列表:
blue
indigo
orange
purple
white
该命令comm colors1 colors2
产生以下输出:
blue
green
indigo
orange
purple
red
white
yellow
其中:
第一列包含以辅音开头和结尾的颜色(在 中colors1
但不在 中colors2
),第二列包含以元音开头和结尾的颜色(在 中colors2
但不在 中colors1
),第三列包含以辅音开头并以元音结尾的颜色(在 和 中colors1
)colors2
。对于您的文件(如您的问题所示),comm fileP.txt fileE.txt
生成
[email protected]:testtest
[email protected]:testtest0
[email protected]:testtest1
[email protected]:testtest2
[email protected]:testtest3
[email protected]:testtest4
[email protected]:testtest5
这些选项有点不直观:-23
表示隐藏第二列和第三列,仅显示第一列(第一个文件中的行,但不在第二个文件中的行)。因此,
$ comm -23 fileP.txt fileE.txt
[email protected]:testtest1
[email protected]:testtest4
请注意,如果文件未排序,此操作将无法正常工作。如果文件未排序,请对其进行排序。
答案2
扩大xenoid 的评论,对文件进行排序并输入
diff fileP.txt fileE.txt | sed -n 's/^< //p'
的输出diff
显示仅在第一个文件中以 开头的行<
,以及仅在第二个文件中以 开头的行>
。sed
仅选择以 开头的行<
并将其删除。