我有一个包含数百万个 DNA 序列的大型 .fna 文件。由于截断引物后出现一些写入错误,我留下了一些序列标题,后面没有序列。一个例子如下所示。我需要删除这些标题以及空行,以便我可以继续我的工作流程脚本。
B2S312_20116609 HWI-ST1128:217:D2HB4ACXX:8:1101:20814:45721 orig_bc=CCGCATAA new_bc=CCGCATAA bc_diffs=0
AACCATGCACCACCTGTATCTGTGTCTAACCAAAGGTCAGAACAACACAATCTCTTGTGTCCTCACAGTATGTCAAGACTT
B4S315_20116610 HWI-ST1128:217:D2HB4ACXX:8:1101:20948:45746 orig_bc=ATATGCCG new_bc=ATATGCCG bc_diffs=0
AACCATGCACCACCTGCACACGACCAACTAAATGCCACCACATCTCTGCAGTGTCGCCGTGCATGTCAAGCCTT
A3C214_20116611 HWI-ST1128:217:D2HB4ACXX:8:1101:20874:45747 orig_bc=GATCCAAC new_bc=GATCCAAC bc_diffs=0
A2C214_20116612 HWI-ST1128:217:D2HB4ACXX:8:1101:21248:45534 orig_bc=CCTAGGAT new_bc=CCTAGGAT bc_diffs=0
AACCGTGCACCACCTGTTTTCTGGCTTCCGAAGAAGAGGAACTATCTCTAGTTCTGTCCATCAATGTCAAGACCT
所以在这个例子中我想删除该A3C214_20116611 HWI-ST1128:217:D2HB4ACXX:8:1101:20874:45747 orig_bc=GATCCAAC new_bc=GATCCAAC bc_diffs=0
行及其下面的空行。
我设法仅使用 sed 删除空行,但找不到适合我的场景的示例。
答案1
sed '$!N;/:.*\n$/d;P;D' <infile
上面的命令在不是最后一行N
的每一行上拉入 ext 行。如果它遇到一个模式空间,其中找到一个冒号并且最后一个字符是一个ewline,它将删除该批次。这意味着对于包含冒号且下一行为空白的行,两者都将被删除。对于所有其他的,它会打印到模式空间中第一个出现的 ewline,然后在从剩下的开始之前删除相同的内容。这使您可以在整个文件中进行一行前瞻。!
$
:
\n
P
\n
D
答案2
(对于下面的解决方案,我假设您希望在每个标题+序列行之前有一个空行。如果您想在后面添加一个空行,请告诉我;这是一个很容易进行的更改。)
使用sed
$ sed -rn 's/(.{106})/\n\1/p' file
B2S312_20116609 HWI-ST1128:217:D2HB4ACXX:8:1101:20814:45721 orig_bc=CCGCATAA new_bc=CCGCATAA bc_diffs=0 AACCATGCACCACCTGTATCTGTGTCTAACCAAAGGTCAGAACAACACAATCTCTTGTGTCCTCACAGTATGTCAAGACTT
B4S315_20116610 HWI-ST1128:217:D2HB4ACXX:8:1101:20948:45746 orig_bc=ATATGCCG new_bc=ATATGCCG bc_diffs=0 AACCATGCACCACCTGCACACGACCAACTAAATGCCACCACATCTCTGCAGTGTCGCCGTGCATGTCAAGCCTT
A2C214_20116612 HWI-ST1128:217:D2HB4ACXX:8:1101:21248:45534 orig_bc=CCTAGGAT new_bc=CCTAGGAT bc_diffs=0 AACCGTGCACCACCTGTTTTCTGGCTTCCGAAGAAGAGGAACTATCTCTAGTTCTGTCCATCAATGTCAAGACCT
怎么运行的
-r
-r
告诉sed
使用扩展正则表达式。-n
-n
sed
除非明确要求,否则不要打印任何行。s/(.{106})/\n\1/p
如果任何行至少有 106 个字符,我们会在开头添加换行符并打印它。
由于空白行没有 106 个字符,因此不会打印它们。
由于没有 DNA 序列的行短于 106 个字符,因此不会打印它们。
打印带有 DNA 序列的行(使其长度为 106 个字符或更长)。因为空白行本身不会被打印,所以我们必须在行的开头添加换行符。从而确保每个 DNA 记录前面都有一个空行。
非GNUsed
如果使用 OSX (BSD),请尝试:
sed -E -n -e 's/(.{106})/\n\1/p' file
使用awk
awk '$6 {print "\n"$0}' file
DNA 序列是该行的第六个字段。因此,对于任何具有非空第六字段的行,我们都会在该行之前打印换行符。
答案3
只是想提一下你可以使用以下方法来做到这一点vi
:
:g/PATTERN/normal 2dd
PATTERN
你要找的东西在哪里。这将在模式下匹配PATTERN
并执行2dd
(删除行 - 2 次) 。normal
答案4
使用 Ex/vi
发出 @ReulSharabin 建议的命令:
ex -s +'g/bc_diffs=0$/d +2' +x file
这类似于:
vim +':g/bc_diffs=0$/d +2' +:x file
(+command = 执行命令;+x
= 保存并退出)
好吧,好吧,这是一个坏主意:我们不应该将这么大的文件加载到内存中