Grep到多个输出文件

mef*_*fju 3 bash awk grep

我有一个巨大的文件(超过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会成功吗?

Dim*_*lov 5

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)


mic*_*ael 5

您可以使用 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)