如果一个文件的部分内容出现在另一个文件中,则打印该文件中的行。两个文件都有数百万行长

如果一个文件的部分内容出现在另一个文件中,则打印该文件中的行。两个文件都有数百万行长

我有两个文件,我们将它们称为123.txt789.txt123.txt2.5M 行长,789.txt65M 行长。有没有什么方法可以使用grep或类似的方法来保留789.txt包含行的任何行123.txt?

中的每行最多有一个重复项789.txt,并且重复的文本将位于该行的开头。我完全陷入困境,在网上找不到任何信息,所以我真的没有任何东西可以开始。它将在服务器上运行,所以我不介意它需要一段时间(我知道它会的)

  • 123.txt:

    hxxp://www.a.com
    hxxp://www.b.com
    hxxp://www.c.com
    
  • 789.txt:

    hxxp://www.a.com/kgjdk-jgjg/
    hxxp://www.b.com/gsjahk123/
    hxxp://www.c.com/abc.txt
    hxxp://www.d.com/sahgsj/
    
  • 期望的输出:

    hxxp://www.a.com/kgjdk-jgjg/
    hxxp://www.b.com/gsjahk123/
    hxxp://www.c.com/abc.txt
    

答案1

您可以使用以下方法轻松完成此操作grep

$ grep -Ff 123.txt 789.txt
http://www.a.com/kgjdk-jgjg/ 
http://www.b.com/gsjahk123/ 
http://www.c.com/abc.txt 

上面的命令将打印文件中789.txt包含123.txt. -f 表示“从该文件读取要搜索的模式”,-F 告诉 grep 将搜索模式视为字符串而不是其默认正则表达式。

123.txt如果 的行包含尾随空格,则这将不起作用grep,会将空格视为模式的一部分来查找,如果它出现在单词中,则不会匹配。例如,模式foo (注意尾随空格)将不匹配foobar。要从文件中删除尾随空格,请运行以下命令:

$ sed 's/ *$//' 123.txt > new_file

然后使用new_filegrep :

$ grep -Ff new_file 789.txt

您也可以在不使用新文件的情况下使用以下i标志来执行此操作:

$ sed -i.bak 's/ *$//' 123.txt

这将更改文件123.txt并保留原始文件的副本,称为123.txt.bak.

(请注意,这种形式的-i标志sed假定您有 GNU sed;对于 BSDsed使用-i .bak,中间有一个空格。)

答案2

如果像您的示例中的文件已排序并且始终遵循该模式,您可以编写它:

join -t/ -1 3 -2 3 123.txt 789.txt |
  sed -n 's,\([^/]*/\)\([^/]*://\)\2,\2\1,p'

这将是最有效率的。

相关内容