我目前正在尝试grep
一个更大的csv文件(3.000.000行)的ID列表(〜5000)。
我想要所有的csv行,包含id文件中的一个id。
我天真的做法是:
cat the_ids.txt | while read line do cat huge.csv | grep $line >> output_file done
但是这需要永远!
有更有效的方法来解决这个问题吗?
尝试
grep -f the_ids.txt huge.csv
此外,由于你的模式似乎是固定的字符串,提供-F
选项可能会加速grep
。
-F, --fixed-strings Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched. (-F is specified by POSIX.)
为此使用grep -f
:
grep -f the_ids.txt huge.csv > output_file
从man grep
:
-f文件, – 文件=文件
从FILE获取模式,每行一个。 空文件包含零模式,因此不匹配任何内容。 (-f由POSIX指定)。
如果你提供一些示例输入,也许我们甚至可以改善grep
条件多一点。
$ cat ids 11 23 55 $ cat huge.csv hello this is 11 but nothing else here and here 23 bye $ grep -f ids huge.csv hello this is 11 but and here 23
grep -f
得到更大的文件不守规矩。 即使使用grep -f
,我们也需要记住一些事情:
-x
选项 -F
-w
来防止部分匹配,而不使用-x
选项 这篇文章对这个主题进行了很好的讨论( grep -f
在大文件上):
这篇文章谈到了grep -vf
:
总之,在大文件上处理grep -f
的最好方法是:
匹配整行:
awk 'FNR==NR {hash[$0]; next} $0 in hash' filter.txt data.txt > matching.txt
匹配第二个文件中的特定字段(在本例中使用','分隔符和字段2):
awk -F, 'FNR==NR {hash[$1]; next} $2 in hash' filter.txt data.txt > matching.txt
和grep -vf
:
匹配整行:
awk 'FNR==NR {hash[$0]; next} !($0 in hash)' filter.txt data.txt > not_matching.txt
匹配第二个文件中的特定字段(在本例中使用','分隔符和字段2):
awk -F, 'FNR==NR {hash[$0]; next} !($2 in hash)' filter.txt data.txt > not_matching.txt