Python 脚本中用于生成 Bash 脚本的 KeyError

KeyError in Python script used to generate Bash scripts

我有一个名为 renaming.py 的 Python 脚本,我想用它来生成许多 Bash 脚本(超过 500 个)。 Python 脚本如下所示:

#!/usr/bin/python

#Script to make multiple Bash scripts based on a .txt file with names of files
#The .txt file contains names of files, one name per line
#The .txt file must be passed as an argument.

import os
import sys

script_tpl="""#!/bin/bash
#BSUB -J "renaming_{line}"
#BSUB -e /scratch/username/renaming_SNPs/renaming_{line}.err
#BSUB -o /scratch/username/renaming_SNPs/renaming_{line}.out
#BSUB -n 8
#BSUB -R "span[ptile=4]"
#BSUB -q normal
#BSUB -P DBCDOBZAK
#BSUB -W 168:00

cd /scratch/username/renaming_SNPs

awk '{sub(/.*/, "_" ,)} 1' {file}.gen > {file}.renamed.gen

"""

with open(sys.argv[1],'r') as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        line = line.strip(".gen")
        script = script_tpl.format(line=line)
        with open('renaming_{}.sh'.format(line), 'w') as output:
            output.write(script)

我作为参数传递给此 Python 脚本的 .txt 文件如下所示:

chr10.10.merged.no_unwanted.formatted.gen
chr10.11.merged.no_unwanted.formatted.gen
chr10.12.merged.no_unwanted.formatted.gen
chr10.13.merged.no_unwanted.formatted.gen
chr10.14.merged.no_unwanted.formatted.gen
chr10.15.merged.no_unwanted.formatted.gen
etc

当我 运行 Python 脚本时,我收到以下错误消息:

Traceback (most recent call last):
  File "renaming.py", line 33, in <module>
    script = script_tpl.format(line=line)
KeyError: 'sub(/'

我不完全确定发生了什么,但这是我的想法

任何帮助将不胜感激。

当您调用 str.format 时,它会尝试格式化 {}s 中的所有内容。

所以这一行就是问题所在:

awk '{sub(/.*/, "_" ,)} 1' {file}.gen > {file}.renamed.gen

因为字符串格式化程序正试图在您的格式调用中找到 kwargs sub(/file,它们不存在,因为您指定的唯一键是 line=line

如果您不想将它们用于格式化,则需要转义大括号。 (格式调用应删除最终字符串中的一对。)

awk '{{sub(/.*/, "_" ,)}} 1' {{file}}.gen > {{file}}.renamed.gen

当您使用 .format 时,字符串中的所有 { } 都会调用字符串格式化。由于您在 awk 命令中使用了这些字符,因此必须对它们进行转义。为此,您将 {{}}:

加倍
script_tpl="""#!/bin/bash
#BSUB -J "renaming_{line}"
#BSUB -e /scratch/username/renaming_SNPs/renaming_{line}.err
#BSUB -o /scratch/username/renaming_SNPs/renaming_{line}.out
#BSUB -n 8
#BSUB -R "span[ptile=4]"
#BSUB -q normal
#BSUB -P DBCDOBZAK
#BSUB -W 168:00

cd /scratch/username/renaming_SNPs

awk '{{sub(/.*/, "_" ,)}} 1' {line}.gen > {line}.renamed.gen

"""

这是relevant docs