unix 如何从列表中查找包含关键字的文件(搜索200万个文件以获得60K关键字)?

rfbsl7qr  于 2023-08-04  发布在  Unix
关注(0)|答案(1)|浏览(134)

我在一个文件夹中有200万个文本文件(实际上是子文件夹,但让我们简化解释)。我在CSV文件中有60 K URL。我想找到所有包含CSV文件中找到的URL之一的文本文件。
我试着一步一步地执行,但得到了一个错误:

# Get all the URLs in column 2 from data.csv and put in a variable
keywords=$(cut -d ',' -f 2 data.csv | tr '\n' '|')
# Search them with grep and find
find ./ -type f -exec grep -E -l "$keywords" {} \;
# Error as follows:
zsh: argument list too long: find

字符串
你知道一个聪明的方法来实现这个规模吗?非常感谢!

更新根据建议改进的版本(但很慢):

find ./ -type f -exec grep -Flf data.txt '{}' +


用这个data.txt

http://www.wikidata.org/entity/Q1002064
http://www.wikidata.org/entity/Q101437
http://www.wikidata.org/entity/Q1020106
...

hs1ihplo

hs1ihplo1#

未测试,因为问题中没有输入/输出示例,但您可能想要这样的东西(假设没有文件名包含换行符):

find . -type f |
awk '
    BEGIN {
        while ( (getline url < "data.csv") > 0 ) {
            tgtUrls[url]
        }
    }
    NR == FNR {
        ARGV[ARGC++] = $0
        next
    }
    {
        for ( url in tgtUrls ) {
            line = $0
            while ( pos = index(line,url) ) {
                if ( substr(line,pos+length(url),1) !~ /[[:alnum:]_]/ ) {
                    print FILENAME
                    next
                }
                line = substr(line,pos+1)
            }
        }
    }
'

字符串
但是你需要考虑字符串(pos = index($0,url))+ regexp(substr($0,pos+length(url),1) !~ /[[:alnum:]_]/)的比较组合是否足以检查URL在当前行中是否真的匹配,并且不是较长URL的子字符串,例如:http://example.com错误匹配http://example.company.net,为您的目的,拿出一些样本输入/输出,将测试所有的雨天情况,您可以在您的数据,错误匹配是可能的。
如果index()比较的次数为60,000 URLs * 2 million files * the number of lines in each file,那么上述操作需要一段时间才能运行。

相关问题