我有一个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
任何人都有解决方案让我的文件格式正确吗?谢谢!
答案 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 Program,The 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')