如何调整FASTA文件每行字符数为60?fold命令无效的解决办法
解决FASTA文件按每行60字符格式化并添加前缀空格的问题
问题描述
用户原始FASTA文件:
>abc AGAATTCGTCTTGCTCTATTCACCCTTACTTTTCTTCTTGCCCGTTCTCTTTCTTAGTATGAATCCAGTA TGCCTGCCTGTAATTGTTGCGCCCTACCTCTTTTGGCTGGCGGCTATTGCCGCCTCGTGTTTCACGGCCT CAGTTAGTACCGTTGTGACCGCCACCGGCTTGGCCCTCTCACTTCTACTCTTGGCAGCAGTGGCCAGCTC ATATGCCGCTGCACAAAGGAAACTGCTGACACCGGTGACAGTGCTTACTGCGGTTGTCACTTGTGAGTAC
需要调整为标题行前加3个空格、序列行前加4个空格且每行序列为60字符的目标格式:
>abc AGAATTCGTCTTGCTCTATTCACCCTTACTTTTCTTCTTGCCCGTTCTCTTTCTTAGTAT GAATCCAGTATGCCTGCCTGTAATTGTTGCGCCCTACCTCTTTTGGCTGGCGGCTATTGC CGCCTCGTGTTTCACGGCCTCAGTTAGTACCGTTGTGACCGCCACCGGCTTGGCCCTCTC ACTTCTACTCTTGGCAGCAGTGGCCAGCTCATATGCCGCTGCACAAAGGAAACTGCTGAC
使用fold -w 60 myfile.fasta > out.fa无法满足需求,该命令会拆分原有换行的序列片段,且无法添加前缀空格,输出如下:
>abc AGAATTCGTCTTGCTCTATTCACCCTTACTTTTCTTCTTGCCCGTTCTCTTTCTTAGTAT GAATCCAGTA TGCCTGCCTGTAATTGTTGCGCCCTACCTCTTTTGGCTGGCGGCTATTGCCGCCTCGTGT TTCACGGCCT CAGTTAGTACCGTTGTGACCGCCACCGGCTTGGCCCTCTCACTTCTACTCTTGGCAGCAG TGGCCAGCTC ATATGCCGCTGCACAAAGGAAACTGCTGACACCGGTGACAGTGCTTACTGCGGTTGTCAC TTGTGAGTAC ACACGCACCATTTACAATGCATGATGTTCGTGAGATTGATCTGTCTCTAACAGTTCACTT
解决方案
方法1:使用awk脚本
awk可合并分散的序列行,再按60字符拆分并添加前缀空格:
awk ' /^>/ { if (seq != "") { while (length(seq) > 0) { print " " substr(seq, 1, 60) seq = substr(seq, 61) } seq = "" } print " " $0 next } { seq = seq $0 } END { while (length(seq) > 0) { print " " substr(seq, 1, 60) seq = substr(seq, 61) } }' myfile.fasta > out.fa
方法2:sed+fold组合命令
先合并所有序列行,再处理前缀空格和拆分:
sed '/^>/!{:a;N;s/\n//;ta}' myfile.fasta | awk '/^>/ {print " " $0; next} {print " " $0}' | fold -w 64 | sed 's/^ //;s/^/ /'
命令解释:
sed '/^>/!{:a;N;s/\n//;ta}':合并所有非标题行的序列内容awk:给标题行加3个空格,合并后的序列行加4个空格fold -w 64:因序列行前缀有4个空格,总长度设为64以保证实际序列为60字符- 最后一段
sed:确保拆分后的每行都保留4个前缀空格
方法3:Python脚本
适合需要自定义逻辑的场景:
with open("myfile.fasta", "r") as infile, open("out.fa", "w") as outfile: seq_buffer = "" for line in infile: stripped_line = line.strip() if not stripped_line: continue if stripped_line.startswith(">"): # 处理之前缓存的序列 if seq_buffer: for i in range(0, len(seq_buffer), 60): outfile.write(f" {seq_buffer[i:i+60]}\n") seq_buffer = "" # 写入带前缀的标题行 outfile.write(f" {stripped_line}\n") else: seq_buffer += stripped_line # 处理文件末尾的最后一段序列 if seq_buffer: for i in range(0, len(seq_buffer), 60): outfile.write(f" {seq_buffer[i:i+60]}\n")
内容的提问来源于stack exchange,提问作者pythonbeginner
相关产品推荐
相关产品推荐

