Как избежать SyntaxError: неожиданный символ после символа продолжения строки - PullRequest
0 голосов
/ 10 января 2020

Я хочу написать скрипт python, который позволит мне извлечь часть текста из нескольких файлов в каталоге и сохранить их в новом файле. Я пытаюсь использовать модуль подпроцесса, но в указанном c коде я использую 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

И я хочу сделать один большой вывод, используя для l oop более 100 других файлов, таких как пример ввода

Ответы [ 2 ]

3 голосов
/ 10 января 2020

Вот чистая 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, является кодом возврата конвейера оболочки (0 для успеха, другие числа означают uniq сбой или произошла ошибка синтаксического анализа оболочки). Если вы хотите обработать вывод подпроцесса, используйте subprocess.check_output() или его современную замену subprocess.run().

Вы также ничего не делали с data, который вы прочитали, и конвейер оболочки был также не получая никакого ввода.

Стилистически, мы предпочитаем менеджер контекста with вместо явного открытия и закрытия файлов (вы также забыли закрыть file_data).

Ваш код будет запись Genome GO_term один раз для каждого входного файла; Я сохранил эту логику c, но, наверное, вы не хотели, чтобы она работала таким образом. grep в вашем оригинале отбрасывает этот вывод; конечно, если вы действительно этого не хотите, не печатайте его в первую очередь.

Аналогично, я укажу, что uniq будет запускаться один раз для каждого входного файла, поэтому, если несколько входные файлы содержат одинаковое значение, вы получите дубликаты. Если это не то, что вам нужно, создание пустого набора seen вне for l oop вместо этого делает его глобальным.

... Это не было бы слишком сложно исправить в сценарии оболочки , или; просто запустите Awk для всех входных файлов в одном go. На самом деле тогда вам вообще не понадобится Python здесь (или, как отмечено выше, grep).

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

Обратите также внимание, что uniq удаляет только смежные идентичные строки , В коде Python я предположил, что вы действительно хотите, чтобы каждая строка вывода была уникальной, но это должно быть легко изменить обратно (просто запомните предыдущее напечатанное значение и не печатайте, если оно идентично). И наоборот, было бы несложно реорганизовать скрипт Awk, чтобы он не печатал повторы, используя очень похожие логики c, хотя, конечно, синтаксис Awk будет сильно отличаться от того, как он выглядит в Python.

. Сравните эти два подхода, обратите внимание, насколько кратким является код Awk. Даже если вы увеличите его в четыре раза по размеру и сложности, он все равно будет довольно маленьким и простым для понимания. Но тогда это примерно предел того, что имеет смысл делать в Awk; если вы планируете сделать эту часть более крупной и сложной программы, Python больше подходит для этого. Кроме того, код Python, во всей своей очевидности, довольно легко понять, даже если вы не используете язык каждый день. Боюсь, этого нельзя сказать об Awk. Явная структура кода Python также позволяет легко определить, какая часть может потребоваться изменить, если вы обнаружите или обнаружите новые требования.

0 голосов
/ 10 января 2020
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). Используйте \", чтобы поместить двойные кавычки в строку с двойными кавычками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...