使用grep进行模糊字符串匹配

13

我正在尝试匹配包含字符串ACTGGGTAAACTA的文件中的行。如果我这样做

grep "ACTGGGTAAACTA" file 

它会给我准确匹配的行。是否有一种方法可以允许一定数量的不匹配(替换,插入或删除)?例如,我正在寻找以下序列:

  1. 允许最多3个替换,如“AGTGGGTAACCAA”等。

  2. 插入/删除(具有部分匹配,例如“ACTGGGAAAATAAACTA”或“ACTAAACTA”)


你的意思是类似于“查找ACTGGGTAAACTA或者变化最多3个字母的序列”吗? - Ramón Gil Moreno
3
正则表达式不是一个模糊匹配工具,你需要非常精确地确定要查找的内容。你可以明确声明某些字符可能会缺失(例如,ACTGGGTA{1,3}CTA 可以匹配 ACTGGGTACTAACTGGGTAACTAACTGGGTAAACTA),但是你越是让正则表达式变得“模糊”,就会得到更多不想要的匹配结果。 - JDB
也许类似于在Linux控制台中进行模糊文件搜索。 - emartinelli
可能是Fuzzy regular expressions的重复问题。 - tripleee
5个回答

5
曾经有一个叫做 agrep 的工具用于模糊正则匹配,但是它已经被废弃了。
链接 http://en.wikipedia.org/wiki/Agrep 介绍了一些相关工具的历史和链接。
链接 https://github.com/Wikinaut/agrep 这个仓库看起来像是一个复兴的开源版本,但我还没有测试过。
如果找不到上述两者,可以尝试查找你的发行版是否有tre-agrep

3
你可以使用tre-agrep命令,并使用-E参数指定编辑距离。例如,如果你有一个文件foo
cat <<< EOF > foo
ACTGGGAAAATAAACTA
ACTAAACTA
ACTGGGTAAACTA
EOF

您可以使用编辑距离(edit distance)为9的方式匹配每一行,如下所示:
tre-agrep -s -9 -w ACTGGGTAAACTA foo

输出:

4:ACTGGGAAAATAAACTA
4:ACTAAACTA
0:ACTGGGTAAACTA

1

有一个名为fuzzysearch的Python库(由我编写),它提供了所需的功能。

以下是一些示例代码,应该可以正常工作:

from fuzzysearch import find_near_matches

with open('path/to/file', 'r') as f:
    data = f.read()

# 1. search allowing up to 3 substitutions
matches = find_near_matches("ACTGGGTAAACTA", data, max_substitutions=3)

# 2. also allow insertions and deletions, i.e. allow an edit distance
#    a.k.a. Levenshtein distance of up to 3
matches = find_near_matches("ACTGGGTAAACTA", data, max_l_dist=3)

1
你可以使用fzf来模糊搜索文件中的字符串,方法如下:
cat file | fzf --filter='ACTGGGTAAACTA'

以下代码也可以工作,因为您将文件重定向到STDIN,而fzf从中读取。

fzf --filter='ACTGGGTAAACTA' < file

实际上,您还可以通过启动其用户界面来交互式地查看fzf如何过滤行:

cat file | fzf

在用户界面中,输入一些关键词(以空格分隔)查看筛选效果。
请记住GNU/Linux哲学,特别是模块化概念,它使我们能够独立处理小而强大的部分。我们可以收集这些小部分来制造魔术。 这就是GNU / Linux的美丽之处。

0

简短回答: 不行。

详细回答: 如 @JDB 所说,正则表达式固有的精确性。你可以手动添加不匹配项,例如在某些位置上使用 [ATGC] 代替 A,但是没有办法只允许少量的任何不匹配项。我建议您编写自己的代码来解析它,或尝试在其他地方找到一个DNA解析器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接