删除空行及其上方的行

删除空行及其上方的行

我有一个包含数百万个 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,然后在从剩下的开始之前删除相同的内容。这使您可以在整个文件中进行一行前瞻。!$:\nP\nD

答案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

    -nsed除非明确要求,否则不要打印任何行。

  • 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= 保存并退出)

好吧,好吧,这是一个坏主意:我们不应该将这么大的文件加载到内存中

相关内容