我有一个名为test.txt
的文本文件。我想从test.txt
抓起以>lcl
开头的行,然后提取locus
标记后和右括号]
中的值。我想对location
之后的值做同样的事情。我想要的结果如下所示。如何在python中执行此操作?
所需结果
SS1G_08319 <504653..>506706
SS1G_12233 complement(<502136..>503461)
SS1G_02099 <2692251..>2693298
SS1G_05227 complement(<1032740..>1033620)
test.txt
>lcl|NW_001820825.1_gene_208 [locus_tag=SS1G_08319] [db_xref=GeneID:5486863] [partial=5',3'] [location=<504653..>506706] [gbkey=Gene]
ATGGGCAAAGCTTCTAGGAATAAGACGAAGCATCGCGCTGATCCTACCGCAAAAACTGTTAAGCCACCCA
CTGACCCAGAGCTTGCAGCAATTCGAGTTAACAAAATTCTGCCAATTCTCCAAGATTTACAAAGTGCAGA
CCAGTCAAAGAGATCAACTGCTGCAACTGCCATTGCGAACCTCGTTGACGATACAAAATGTCGAAAGTTA
TTCTTGAGAGAGCAAATTGTTCGTATTCTACTCGAACAAACCCTTACAGACTCAAGCATGGAAACTAGAA
>lcl|NW_001820817.1_gene_205 [locus_tag=SS1G_12233] [db_xref=GeneID:5483157] [partial=5',3'] [location=complement(<502136..>503461)] [gbkey=Gene]
ATGATCTGTAATACGCTCGGTGTTCCACCCTGCAACAGAATTCTTAAGAAATTCTCCGTTGGCGAGAGTC
GTCTCGAAATTCAAGACTCAGTACGAGGCAAAGATGTCTACATCATTCAATCGGGTGGAGGAAAGGCCAA
TGATCACTTCGTGGATCTTTGCATTATGATCTCCGCATGCAAAACTGGCTCTGCCAAGCGCGTCACTGTC
GTCCTTCCTTTGTTTCCTTATTCACGACAACCTGATCTGCCATACAACAAGATTGGCGCACCACTTGCCA
>lcl|NW_001820834.1_gene_1034 [locus_tag=SS1G_02099] [db_xref=GeneID:5493612] [partial=5',3'] [location=<2692251..>2693298] [gbkey=Gene]
ATGGCTTCTGTTTACAAGTCATTATCAAAGACCTCTGGTCATAAAGAAGAAACCCCGACTGGTGTCAAGA
AAAACAAGCAAAGAGTTTTGATCTTGTCTTCAAGAGGAATAACTTACAGGTATATAAATTTGTACCGATG
CGATGCAAAAAATCGCAGGAAAATGCTAACTCTACAACTTAGACATCGACATCTCCTCAATGACCTTGCG
TCCCTACTTCCCCACGGTAGGAAAGATGCGAAACTCGATACCAAGTCAAAGCTTTATCAATTGAATGAAT
>lcl|NW_001820830.1_gene_400 [locus_tag=SS1G_05227] [db_xref=GeneID:5489764] [partial=5',3'] [location=complement(<1032740..>1033620)] [gbkey=Gene]
ATGGCGGACGGATGTAAGTTAATTGATGTTCCTACTATTCCAGACTAATATTTGTTCTCGTCCCTACAAT
GCATTCGGAACGGATGGTACTCAGTTAACTTTGTAACTAATACAACGTCTAGTAAATGACCAAAGAACTG
我是python的新手,所以我想出了类似这样的东西:
results = []
f = open("test.txt", 'r')
while True:
line = f.readline()
if not line:
break
file_name = line.split("locus_tag")[-1].strip()
f.readline() # skip line
data_seq1 = f.readline().strip()
f.readline()
data_seq2 = f.readline().strip()
results.append((file_name, data_seq1))
答案 0 :(得分:4)
我认为,解决此问题的最简单的方法是使用regex
,例如以下示例:
import re
results = []
# Open the file in the 'read' mode
# with statement will take care to close the file
with open('YOUR_FILE_PATH', 'r') as f_file:
# Read the entire file as a one string
data = f_file.read()
# Here we search for the string that begins with '>lcl'
# and in which we find the [locus_tag=...] and [localtion=...]
results = re.findall(r'>lcl.*\[locus_tag=(.*?)\].*\[location=(.*?)\]', data)
for locus, location in results:
print(locus, location)
输出:
SS1G_08319 <504653..>506706
SS1G_12233 complement(<502136..>503461)
SS1G_02099 <2692251..>2693298
SS1G_05227 complement(<1032740..>1033620)
使用dict
作为结果并通过分割行的另一种形式:
import re
results = {}
with open('fichier1', 'r') as f_file:
# Here we split the file's lines into a list
data = f_file.readlines()
for line in data:
# Here we search for the lines that begins by '>lcl'
# and same as the first attempt
results.update(re.findall(r'^>lcl.*\[locus_tag=(.*?)\].*\[location=(.*?)\]', line))
for locus, location in results.items():
print(locus, location)
编辑:创建一个DataFrame
并将其导出到csv
文件中:
import re
from pandas import DataFrame as df
results = {}
with open('fichier1', 'r') as f_file:
data = f_file.readlines()
for line in data:
results.update(re.findall(
r'^>lcl.*\[locus_tag=(.*?)\].*\[location=(.*?)\]',
line
))
df_ = df(
list(results.items()),
index=range(1, len(results) + 1),
columns=['locus', 'location']
)
print(df_)
df_.to_csv('results.csv', sep=',')
它将打印并创建一个名为results.csv
的文件:
locus location
1 SS1G_12233 complement(<502136..>503461)
2 SS1G_08319 <504653..>506706
3 SS1G_05227 complement(<1032740..>1033620)
4 SS1G_02099 <2692251..>2693298
答案 1 :(得分:2)
我想提出两种替代解决方案。一种将使用正则表达式提取行上的任何命名标签集,另一种则是完整的琐事,但显示了一种无需正则表达式的方式。
通用正则表达式解决方案
execute_process(COMMAND some system command
OUTPUT_VARIABLE command_output
)
# ... nothing happens for a few minutes while the process executes
# All of the output from the past few minutes is printed all at once.
message(STATUS ${command_output})
此函数返回一个由您感兴趣的标签作为关键字的字典列表,您将像这样使用它:
PersistableAdapter pa = new PersistableAdapter (product,null,null,null);
pa.load("isImageChanged");
System.out.println("Value is:: "+ pa.get("isImageChanged"));
您可以使用结果来获取所需的确切打印输出:
import re
def get_tags(filename, tags, prefix='>lcl'):
tags = set(tags)
pattern = re.compile(r'\[(.+?)=(.+?)\]')
def parse_line(line):
return {m.group(1): m.group(2) for m in pattern.finditer(line) if m.group(1) in tags}
with open(filename) as f:
return [parse_line(line) for line in f if prefix is None or line.startswith(prefix)]
其优点是您可以使用以后选择的结果,并配置要提取的标签。
没有正则表达式解决方案
此版本只是我写的要显示的内容。请不要模仿它,因为代码是毫无意义的维护负担。
tags = ['locus_tag', 'location']
result = get_tags('test.txt', tags)
此函数的行为与第一个函数相同,但是相比之下,解析函数是一个混乱局面。它的鲁棒性也要差很多,例如因为假设您所有的方括号或多或少都匹配。
这是一个显示两个方法的IDEOne链接:https://ideone.com/X2LKqL