bash – 为什么grep在-w(–word-regexp)标志下如此缓慢和内存密集?

我有一个文件中的id列表和一个数据文件(大小约为3.2Gb),我想提取数据文件中包含id和下一行的行.我做了以下事情:
grep -A1 -Ff file.ids file.data | grep -v "^-" > output.data

这有效,但也提取了不需要的子串,例如,如果id是EA4,它也用EA40拉出线.

所以我尝试使用相同的命令,但将-w(–word-regexp)标志添加到第一个grep以匹配整个单词.但是,我发现我的命令现在运行了> 1小时(而不是~26秒)并且还开始使用10千兆字节的内存,所以我不得不杀死这份工作.

为什么添加-w会使命令变得如此缓慢并且内存占用?如何有效地运行此命令以获得所需的输出?谢谢

file.ids看起来像这样:

>EA4
>EA9

file.data如下所示:

>EA4 text
data
>E40 blah
more_data
>EA9 text_again
data_here

output.data看起来像这样:

>EA4 text
data
>EA9 text_again
data_here
grep -F字符串文件只是在文件中查找字符串的出现,但grep -w -F字符串文件必须检查字符串前后的每个字符,以查看它们是否是单词字符.这是一项额外的工作,其中一个可能的实现方法是首先将行分成每个可能的非单词字符分隔的字符串,当然这些字符串会重叠,这样可能占用大量内存,但如果这是导致记忆的话,那就是idk用法与否.

在任何情况下,grep只是这个工作的错误工具,因为你只想匹配输入文件中的特定字段,你应该使用awk:

$awk 'NR==FNR{ids[$0];next} /^>/{f=($1 in ids)} f' file.ids file.data
>EA4 text
data
>EA9 text_again
data_here

以上假设您的“数据”行不能以>开头.如果他们可以告诉我们如何识别数据线与id线.

请注意,无论id行之间有多少数据行,即使有0或100,上述内容也会有效:

$cat file.data
>EA4 text
>E40 blah
more_data
>EA9 text_again
data 1
data 2
data 3

$awk 'NR==FNR{ids[$0];next} /^>/{f=($1 in ids)} f' file.ids file.data
>EA4 text
>EA9 text_again
data 1
data 2
data 3

此外,您不需要将输出传递给grep -v:

grep -A1 -Ff file.ids file.data | grep -v "^-" > output.data

只需在一个脚本中完成所有操作:

awk 'NR==FNR{ids[$0];next} /^>/{f=($1 in ids)} f && !/^-/' file.ids file.data

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...