![逐行比较两个文件,如果在文件 2 中未找到(全部或部分)文件 1 的模式,则打印文件 1 的行](https://linux22.com/image/129321/%E9%80%90%E8%A1%8C%E6%AF%94%E8%BE%83%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%9C%A8%E6%96%87%E4%BB%B6%202%20%E4%B8%AD%E6%9C%AA%E6%89%BE%E5%88%B0%EF%BC%88%E5%85%A8%E9%83%A8%E6%88%96%E9%83%A8%E5%88%86%EF%BC%89%E6%96%87%E4%BB%B6%201%20%E7%9A%84%E6%A8%A1%E5%BC%8F%EF%BC%8C%E5%88%99%E6%89%93%E5%8D%B0%E6%96%87%E4%BB%B6%201%20%E7%9A%84%E8%A1%8C.png)
我有两个文件:
文件1(搜索):
1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
GACGGAGGATGCAAGTGTTATCCGGAAT
3
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCC
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG
文件2(模式):
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGC
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCG
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCC
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCCGTAG
我需要的是:
1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
3
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG
这意味着,我需要一个脚本来搜索模式文件中的搜索行,如果可以完全或部分找到搜索行(对于“2”后面的行),则不应写入它们,但是文件 1 的所有其他行。
我尝试了该论坛中找到的许多 grep 和 awk 脚本,但没有一个满足我的需要,例如
awk 'FN==NR {exclude[$0];next} !($0 in exclude)' file2 file1
或者
awk 'NR==FNR{a[$1]++;next} !($1 in a) {print $1} {next}' file2 file1
我也尝试过 grep。
无论如何,所有尝试过的脚本都只是找到完全匹配的模式,而不是部分匹配的模式......
有人有想法吗?
答案1
使用awk
脚本:
NR == FNR { seq[++n] = $1; next }
{
header = $0
getline
for (i = 1; i <= n; ++i) {
if (match(seq[i], $0) > 0) {
print header
next
}
}
print header
print
}
运行它:
$ awk -f script.awk file2 file1
1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
3
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG
该脚本首先将 2000 个序列从 读取file2
到数组 中seq
,然后从 中读取标头,file1
然后读取来自 的序列file1
(使用getline
)。然后它遍历数组seq
以查找包含当前序列的序列file1
。如果找到这样的序列,则打印标题,并且脚本继续执行 中的下一行file1
。否则,将打印标题和序列。
该脚本假定file1
包含交替的标题行和序列行,并且绝对不包含多行序列。
以下是相同的脚本,但使用 DRY 原则(“不要重复自己”):
NR == FNR { seq[++n] = $1; next }
{
header = $0
getline
found = 0
for (i = 1; i <= n; ++i) {
if (match(seq[i], $0) > 0) {
found = 1
break
}
}
print header
if (!found) print
}
答案2
awk
+grep
解决方案:
awk '/^[^>0-9]/{
m = ""; cmd = sprintf("grep -m1 %s file2", $0);
cmd | getline m; close(cmd);
if (m) next;
}1' file1
cmd
- 关键grep
命令m
- 变量填充可能的匹配项
输出:
1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
3
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG
答案3
grep -vxf <(grep -of file_1 file_2 | sort -u) file_1
文件_1
1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
GACGGAGGATGCAAGTGTTATCCGGAAT
3
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCC
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG
文件_2
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGC
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCG
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCC
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCCGTAG
输出
1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
3
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG