如何避免语法错误:行连续字符后出现意外字符

2024-10-01 15:34:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我想编写一个python脚本,它允许我从目录中的多个文件中提取部分文本,并将它们保存在一个新文件中。我试图使用子流程模块,但在我使用awk的特定代码中,由于这个原因,系统给了我语法错误:SyntaxError: unexpected character after line continuation character。您能告诉我如何避免这种情况吗?以下是我编写的代码:

import subprocess as sp

f = open(go_term_file, "a")

cmd = "awk -F "\t" 'BEGIN {print "Genome  GO_term"} {print $1 "\t" $14}' | grep "GO:" | uniq"

for file in glob.glob("*_protein.faa.tsv"):
        file_data = open(file, "r")
        data = file_data.read()
        go_terms = sp.call(cmd.split())
        f.write(go_terms)
f.close()

我曾尝试将\t写为\\t,但无法避免语法错误

补充说明: 以下是示例输入:

MGA_1946|00002511_S689_QC_contigs.fasta_19420   d58ff50ceda18d9b393a7d3694995f79    526 Pfam    PF01433 Peptidase family M1 domain  6   87  6.9E-16 T   07-01-2020  IPR014782   Peptidase M1, membrane alanine aminopeptidase   GO:0008237|GO:0008270
MGA_2039|00002511_S689_QC_contigs.fasta_20350   83a22d41925835b06417f1e7e7b4f5e1    660 SUPERFAMILY SSF47323        444 645 1.74E-53    T   07-01-2020  IPR009080   Aminoacyl-tRNA synthetase, class Ia, anticodon-binding  GO:0000166|GO:0004812|GO:0005524|GO:0006418
MGA_2039|00002511_S689_QC_contigs.fasta_20350   83a22d41925835b06417f1e7e7b4f5e1    660 Gene3D  G3DSA:3.90.740.10       45  185 2.0E-55 T   07-01-2020  IPR009008   Valyl/Leucyl/Isoleucyl-tRNA synthetase, editing domain  GO:0002161|GO:0006418
MGA_2039|00002511_S689_QC_contigs.fasta_20350   83a22d41925835b06417f1e7e7b4f5e1    660 Pfam    PF00133 tRNA synthetases class I (I, L, M and V)    2   424 4.6E-156T07-01-2020 IPR002300   Aminoacyl-tRNA synthetase, class Ia GO:0000166|GO:0004812|GO:0005524|GO:0006418
MGA_2039|00002511_S689_QC_contigs.fasta_20350   83a22d41925835b06417f1e7e7b4f5e1    660 PRINTS  PR00986 Valyl-tRNA synthetase signature 336 354 4.8E-30 T   07-01-2020  IPR002303   Valine-tRNA ligase  GO:0000166|GO:0004832|GO:0005524|GO:0006438 

这是示例输出:

MGA_1946|00002511_S689_QC_contigs.fasta_19420 GO:0008237|GO:0008270
MGA_2039|00002511_S689_QC_contigs.fasta_20350 GO:0000166|GO:0004812|GO:0005524|GO:0006418
MGA_2039|00002511_S689_QC_contigs.fasta_20350 GO:0002161|GO:0006418
MGA_2039|00002511_S689_QC_contigs.fasta_20350 GO:0000166|GO:0004812|GO:0005524|GO:0006418
MGA_2039|00002511_S689_QC_contigs.fasta_20350 GO:0000166|GO:0004832|GO:0005524|GO:0006438

我想通过对大约100个其他文件(如示例输入)使用for循环来生成一个大输出


Tags: 文件go示例dataclassfastafileawk
2条回答

这里是一个纯Python的重新实现

with open(go_term_file, "a") as f:
    for file in glob.glob("*_protein.faa.tsv"):
        f.write("Genome GO_term\n")
        with open(file, "r") as file_data:
            seen = set()
            for line in file_data:
                fields = line.strip("\n").split("\t")
                try:
                    value = "{0}\t{1}\n".format(fields[0], fields[13]])
                except IndexError:
                    continue
                if "GO:" in value:
                    if value not in seen:
                        f.write(value)
                    seen.add(value)

在打印任何内容之前,检查Awk部分中已有的GO:也会使Awk脚本受益

请注意,这也修复了Python代码中的几个错误

来自subprocess.call()的输出仅显示在标准输出上,Python根本不可用;从call中获得的返回值是shell管道的返回代码(0表示成功,其他数字表示uniq失败或存在shell解析错误)。如果要处理子进程的输出,请使用subprocess.check_output()或它的现代替代品subprocess.run()

您也没有对读入的data执行任何操作,shell管道也没有接收任何输入

在风格上,我们更喜欢with上下文管理器,而不是显式地打开和关闭文件(您也忘了关闭file_data

您的代码将为每个输入文件写入一次Genome GO_term;我保留了这个逻辑,但我猜也许你真的不希望它以这种方式工作。原始文件中的grep将丢弃此输出;当然,如果你真的不想要它,首先不要打印它

类似地,我将指出uniq将在每个输入文件中运行一次,因此如果多个输入文件包含相同的值,您将得到重复的值。如果这不是您想要的,那么在for循环之外创建空的seen集将使其成为全局的

。。。这在shell脚本中也不会太难修复;只需在所有输入文件上一次性运行Awk。实际上,这里根本不需要Python(或者,如上所述,grep

awk -F "\t" 'FNR==1 {print "Genome  GO_term"}
  $14 ~ /GO:/ {print $1 "\t" $14}' *_protein.faa.tsv |
uniq

还要注意的是uniq只删除相邻的相同的行。在Python代码中,我假设您真的希望每个输出行都是唯一的,但这应该很容易更改回来(只要记住前面打印的值,如果这个值相同,就不要打印)。相反,使用非常相似的逻辑重构Awk脚本以不打印重复并不困难,尽管Awk语法与Python中的语法有很大不同

为了对比这两种方法,请注意Awk代码要简洁得多。即使你把它的大小和复杂度扩大到原来的四倍,它仍然很小,很容易理解。但这大概就是在Awk中做什么有意义的极限;如果您计划将这一部分变成更大、更复杂的程序,那么Python更适合这样做。此外,Python代码非常明确,即使您不是每天都使用该语言,也很容易理解。恐怕不能对Awk说同样的话。Python代码的显式结构还可以很容易地看出,如果您发现或发现新的需求,哪些部分可能需要更改

import subprocess as sp

f = open(go_term_file, "a")

cmd = "awk -F \"\t\" 'BEGIN {print \"Genome  GO_term\"} {print $1 \"\t\" $14}' | grep \"GO:\" | uniq"

for file in glob.glob("*_protein.faa.tsv"):
        file_data = open(file, "r")
        data = file_data.read()
        go_terms = sp.call(cmd.split())
        f.write(go_terms)
f.close()

所有内容都应该放在引号中,或者它是真正的python代码(\在python中是行连续字符。使用\"将双引号放在双引号字符串中

相关问题 更多 >

    热门问题