我有一个巨大的文件(超过6GB)和大约1000个模式.我希望提取线匹配每个模式以分隔文件.例如我的模式是:
1
2
Run Code Online (Sandbox Code Playgroud)
我的档案:
a|1
b|2
c|3
d|123
Run Code Online (Sandbox Code Playgroud)
作为输出,我想有2个文件:
1:
a|1
d|123
Run Code Online (Sandbox Code Playgroud)
2:
b|2
d|123
Run Code Online (Sandbox Code Playgroud)
我可以通过多次greping文件来做到这一点,但对1000个模式和大文件来说效率很低.我也尝试过这样的事情:
grep -f pattern_file huge_file
Run Code Online (Sandbox Code Playgroud)
但它只会产生1个输出文件.我无法对我的庞大文件进行排序 - 这需要花费很多时间.也许AWK会成功吗?
awk -F\| 'NR == FNR {
patt[$0]; next
}
{
for (p in patt)
if ($2 ~ p) print > p
}' patterns huge_file
Run Code Online (Sandbox Code Playgroud)
使用一些awk实现,您可能会达到最大打开文件数限制.如果是这种情况,请告诉我,以便我可以发布替代解决方案.
PS:这个版本一次只能打开一个文件:
awk -F\| 'NR == FNR {
patt[$0]; next
}
{
for (p in patt) {
if ($2 ~ p) print >> p
close(p)
}
}' patterns huge_file
Run Code Online (Sandbox Code Playgroud)
您可以使用 bash“进程替换”来完成此操作(如果我理解问题),例如,请考虑以下示例数据:
$ cal -h
September 2013
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Run Code Online (Sandbox Code Playgroud)
然后可以grep在单个命令中将选择行放到不同的输出文件中,如下所示:
$ cal -h \
| tee >( egrep '1' > f1.txt ) \
| tee >( egrep '2' > f2.txt ) \
| tee >( egrep 'Sept' > f3.txt )
Run Code Online (Sandbox Code Playgroud)
在这种情况下,每个都grep在处理整个数据流(这可能是也可能不是您想要的:与仅运行并发grep进程相比,这可能不会节省大量时间):
$ more f?.txt
::::::::::::::
f1.txt
::::::::::::::
September 2013
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
::::::::::::::
f2.txt
::::::::::::::
September 2013
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
::::::::::::::
f3.txt
::::::::::::::
September 2013
Run Code Online (Sandbox Code Playgroud)