我有两个文件,我们将它们称为123.txt
和789.txt
。123.txt
2.5M 行长,789.txt
65M 行长。有没有什么方法可以使用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_file
grep :
$ 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'
这将是最有效率的。