删除FASTA文件中的换行符

时间:2013-04-06 23:14:31

标签: unix awk fasta

我有一个fasta文件,其中序列用换行符分解。我想删除换行符。这是我的文件示例:

>accession1
ATGGCCCATG
GGATCCTAGC
>accession2
GATATCCATG
AAACGGCTTA

我想把它转换成这个:

>accession1
ATGGCCCATGGGATCCTAGC
>accession2
GATATCCATGAAACGGCTTA

我找到了一个潜在的解决方案on this site,如下所示:

cat input.fasta | awk '{if (substr($0,1,1)==">"){if (p){print "\n";} print $0} else printf("%s",$0);p++;}END{print "\n"}' > joinedlineoutput.fasta

但是,这会在每个条目之间放置一个额外的换行符,因此文件如下所示:

>accession1
ATGGCCCATGGGATCCTAGC

>accession2
GATATCCATGAAACGGCTTA

我是一个awk noob,但我开始修改命令。我的猜测是if (p){print "\n";}是罪魁祸首...可能print "\n"正在添加两个换行符。我无法弄清楚如何只添加一个换行符...这可能很简单,但就像我说的那样,我是一个菜鸟。这是我的(不成功)解决方案:

awk '{if (substr($0,1,1)==">"){print "\n"$0} else printf("%s",$0);p++;}END{print "\n"}' input.fasta > joinedoutput.fasta

但是,这会在文件开头添加一个空行,因为它在打印第一个入藏号之前总是打印一个新行:

{empty line} 
>accession1
ATGGCCCATGGGATCCTAGC
>accession2
GATATCCATGAAACGGCTTA

任何人都有解决方案让我的文件格式正确吗?谢谢!

9 个答案:

答案 0 :(得分:11)

awk计划:

% awk '!/^>/ { printf "%s", $0; n = "\n" } 
/^>/ { print n $0; n = "" }
END { printf "%s", n }
' input.fasta

将屈服:

>accession1
ATGGCCCATGGGATCCTAGC
>accession2
GATATCCATGAAACGGCTTA

说明:

在不以>开头的行上,打印没有换行符的行并存储换行符(在变量n中)以供日后使用。

在以>开头的行上,打印存储的换行符(如果有)和行。重置n,以防这是最后一行。

如果需要,请以换行符结束。

注意:

  

默认情况下,变量初始化为空字符串。没有必要在中明确“初始化”变量,这是您在和大多数其他传统语言中所做的。

- 6.1.3.1 Using Variables in a ProgramThe GNU Awk User's Guide

答案 1 :(得分:4)

还有另一个awk单行,应该适合你的情况。

awk '/^>/{print s? s"\n"$0:$0;s="";next}{s=s sprintf("%s",$0)}END{if(s)print s}' file

答案 2 :(得分:4)

接受的解决方案很好,但并不是特别的AWKish。请考虑使用此代码:

 awk '/^>/ { print (NR==1 ? "" : RS) $0; next } { printf "%s", $0 } END { printf RS }' file

说明:

对于以>开头的行,请打印该行。如果该行不是文件中的第一行,则使用三元运算符来打印前导换行符。对于不以>开头的行,请打印没有尾随换行符的行。由于文件中的最后一行不以>开头,因此请使用END块打印最终换行符。

请注意,通过设置空输出记录分隔符,启用默认打印并重新分配以>开头的行,也可以更简单地编写上述内容。尝试:

awk -v ORS= '/^>/ { $0 = (NR==1 ? "" : RS) $0 RS } END { printf RS }1' file

答案 3 :(得分:2)

我会使用sed。使用GNU sed

sed ':a; $!N; /^>/!s/\n\([^>]\)/\1/; ta; P; D' file

结果:

>accession1
ATGGCCCATGGGATCCTAGC
>accession2
GATATCCATGAAACGGCTTA

说明:

创建标签a。如果该行不是文件中的最后一行,请将其附加到模式空间。如果该行不以字符>开头,请执行替换s/\n\([^>]\)/\1/。如果自读取最后一个输入行以来替换成功,则转移到标签a。打印到当前模式空间的第一个嵌入换行符。如果模式空间不包含换行符,则启动正常的新循环,就像发出d命令一样。否则,删除模式空间中直到第一个换行符的文本,然后使用生成的模式空间重新启动循环,而不读取新的输入行。

答案 4 :(得分:0)

另一种变化: - )

awk '!/>/{printf( "%s", $0);next}
     NR>1{printf( "\n")} 
     END {printf"\n"}
     7' YourFile

答案 5 :(得分:0)

您可能对bioawk感兴趣,它是awk的改编版本,已调整为可处理fasta文件

bioawk -c fastx '{ gsub(/\n/,"",seq); print ">"$name; print $seq }' file.fasta

注意:BioAwk基于Brian Kernighan's awk中记录的"The AWK Programming Language", by Al Aho, Brian Kernighan, and Peter Weinberger (Addison-Wesley, 1988, ISBN 0-201-07981-X) 。我不确定该版本是否与POSIX兼容。

答案 6 :(得分:0)

使用此Perl单行代码,它可以完成在这种情况和类似情况下必需的所有常见重新格式化:除去序列中的换行符和空格(这也将取消包装序列),但不更改序列头行。请注意,与其他答案不同,此方法可以正确处理文件中的前导和尾随空格/换行符:

# Create the input for testing:

cat > test_unwrap_in.fa <<EOF

>seq1 with blanks
ACGT ACGT ACGT
>seq2 with newlines
ACGT

ACGT

ACGT

>seq3 without blanks or newlines
ACGTACGTACGT

EOF

# Reformat with Perl:

perl -ne 'chomp; if ( /^>/ ) { print "\n" if $n; print "$_\n"; $n++; } else { s/\s+//g; print; } END { print "\n"; }' test_unwrap_in.fa > test_unwrap_out.fa

输出:

>seq1 with blanks
ACGTACGTACGT
>seq2 with newlines
ACGTACGTACGT
>seq3 without blanks or newlines
ACGTACGTACGT

Perl单行代码使用以下命令行标志:
-e:告诉Perl在代码中而不是在文件中查找代码。
-n:一次循环输入一行,默认情况下将其分配给$_

chomp:除去输入行分隔符(* NIX上的\n)。
if ( /^>/ ):测试当前行是否为序列标题行。
$n:此变量开头是未定义的(false),在看到第一个序列标头后为true,在这种情况下,我们将额外打印换行符。该换行符在每个序列的末尾,从第一个序列开始。
END { print "\n"; }:在最后一个序列之后打印最后的换行符。
s/\s+//g; print;:如果当前行是序列(不是标题),请删除所有空白并在不使用换行符的情况下进行打印。

答案 7 :(得分:0)

不要重新发明轮子。如果目标只是删除多行fasta文件(展开fasta文件)中的换行符,请使用任何专门的生物信息学工具,例如seqtk,如下所示:

seqtk seq -l 0 input_file

示例:

# Create the input for testing:

cat > test_unwrap_in.fa <<EOF

>seq1 with blanks
ACGT ACGT ACGT
>seq2 with newlines
ACGT

ACGT

ACGT

>seq3 without blanks or newlines
ACGTACGTACGT

EOF

# Unwrap lines:

seqtk seq -l 0 test_unwrap_in.fa > test_unwrap_out.fa

cat test_unwrap_out.fa

输出:

>seq1 with blanks
ACGT ACGT ACGT
>seq2 with newlines
ACGTACGTACGT
>seq3 without blanks or newlines
ACGTACGTACGT

要安装seqtk,您可以使用例如conda install seqtk

另请参见:

seqtk的用法:

seqtk seq

Usage:   seqtk seq [options] <in.fq>|<in.fa>

Options: ...
         -l INT    number of residues per line; 0 for 2^32-1 [0]

答案 8 :(得分:0)

到目前为止,反应很好。

这是在Python中执行此操作的有效方法:

def read_fasta(fasta):
    with open(fasta, 'r') as fast:
        headers, sequences = [], []
        for line in fast:
            if line.startswith('>'):
                head = line.replace('>','').strip()
                headers.append(head)
                sequences.append('')
            else :
                seq = line.strip()
                if len(seq) > 0:
                    sequences[-1] += seq
    return (headers, sequences)


def write_fasta(headers, sequences, fasta):
    with open(fasta, 'w') as fast:
        for i in range(len(headers)):
            fast.write('>' + headers[i] + '\n' + sequences[i] + '\n')

您可以使用上述功能从Fasta文件中检索序列/标题,而无需换行,对其进行操作并写回fasta文件。

headers, sequences = read_fasta('input.fasta')
new_headers = do_something(headers)
new_sequences = do_something(sequences)
write_fasta(new_headers, new_sequences, 'input.fasta')