2

我有一个带有 2M 条目的大文本文件 largeFile 和另一个带有 1M 整体的较小文本文件..

较小文件 File2 中的所有条目都在 File1 中

较大文件中条目的格式是..

helloworld_12345_987654312.zip
helloWorld_12344_987654313.zip
helloWOrld_12346_987654314.zip

较小的文件包含类似的数据

987654312
987654313

即文件扩展名.zip之前文件名的最后一部分,有人可以指点我如何实现这一点

我的尝试是在较小的文件上运行一个循环并对较大的文件执行 grep 并继续删除条目如果在较大的文件中找到该文件.. 所以在过程结束时我将丢失的条目留在文件中.

尽管此解决方案有效,但效率低下且粗糙..有人可以为这个问题提出更好的方法吗

4

2 回答 2

2

Grep 有一个-f从文件中读取模式的开关。-v将其与仅打印不匹配的行结合起来,您就有了一个优雅的解决方案。由于您的模式是固定字符串,因此您可以在使用-F.

grep -F -v -f smallfile bigfile

我写了一个python脚本来生成一些测试数据:

bigfile = open('bigfile', 'w')
smallfile = open('smallfile', 'w')

count = 2000000
start = 1000000

for i in range(start, start + count):
  bigfile.write('foo' + str(i) + 'bar\n')
  if i % 2:
    smallfile.write(str(i) + '\n')

bigfile.close()
smallfile.close()

以下是我仅使用 2000 行(将计数设置为 2000)运行的一些测试,因为对于更多行,运行 grep 所需的时间-F变得荒谬。

$ time grep -v -f smallfile bigfile > /dev/null

real    0m3.075s
user    0m2.996s
sys 0m0.028s

$ time grep -F -v -f smallfile bigfile > /dev/null

real    0m0.011s
user    0m0.000s
sys 0m0.012s

--mmap根据手册页,Grep 也有一个可以提高性能的开关。在我的测试中没有性能提升。

对于这些测试,我使用了 200 万行。

$ time grep -F -v -f smallfile bigfile > /dev/null

real    0m3.900s
user    0m3.736s
sys 0m0.104s

$ time grep -F --mmap -v -f smallfile bigfile > /dev/null

real    0m3.911s
user    0m3.728s
sys 0m0.128s
于 2013-08-29T11:04:12.583 回答
1

使用grep. 您可以将较小的文件指定为从(使用-f filename)获取模式的文件,并执行 a-v以获取与模式不匹配的行。

由于您的模式看起来是固定的,您还可以提供-F可以加快速度的选项grep

以下内容应该是不言自明的:

$ cat big 
helloworld_12345_987654312.zip
helloWorld_12344_987654313.zip
helloWOrld_12346_987654314.zip
$ cat small 
987654312
987654313
$ grep -F -f small big      # Find lines matching those in the smaller file
helloworld_12345_987654312.zip
helloWorld_12344_987654313.zip
$ grep -F -v -f small big   # Eliminate lines matching those in the smaller file
helloWOrld_12346_987654314.zip
于 2013-08-29T11:04:06.320 回答