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

2024-06-01 01:35:03 发布

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

我有一个Python脚本重命名.py我想用它来生成许多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 "_" $3,$2)} 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文件如下所示:

^{pr2}$

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

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

我不太清楚发生了什么事,但我的想法是这样的

  • 33号线出问题了-不知道是什么问题。我以前也用过类似的脚本。在第33行中,我将用.txt文件中的条目替换script_tpl中的所有{line}实例(这种情况发生500次,对于.txt文件的每一行)。

  • 我被这个错误弄糊涂了。我正在使用Linux HPC服务器(使用Mac笔记本电脑)。当直接将awk命令输入终端(作为Bash命令)时,我已经成功地使用了这个awk命令。但是,当我试图将Python作为一个变量“打印”到脚本中时,Python可能会感到困惑。。

任何帮助都将不胜感激。在


Tags: txt脚本bashaswithlineusernamescript
2条回答

当您使用.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 "_" $3,$2)}} 1' {line}.gen > {line}.renamed.gen

"""

这是relevant docs。在

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

所以这条线就是问题所在:

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

因为字符串格式化程序正试图在您的format调用中找到kwargs sub(/和{},这两个参数不存在,因为您指定的唯一键是line=line。在

如果不希望在格式化时考虑这些内容,则需要转义大括号。(format调用应该删除最后一个字符串中的一个对。)

^{pr2}$

相关问题 更多 >