2011-07-22 63 views
2

目前,我有一个脚本,它执行以下操作。如果我与行的文本文件:如何扩展这个搜索和替换python脚本以接受来自命令行的变量?

<<Name>> is at <<Location>>. 
<<Name>> is feeling <<Emotion>>. 

该脚本将在此输入文件作为命令行参数,并提示输入变量的用户:

Name? Bob 
Location? work 
Emotion? frustrated 

注意,名称只是有一次问。该脚本还将输出文件作为参数,并将在文件中放入以下内容。

Bob is at work. 
Bob is feeling frustrated. 

现在我试图扩展脚本,以便我可以从命令行输入变量(就好像我已经知道它会问什么了)。所以命令就像(在这种情况下):

python script.py infile outfile Bob work frustrated 

它会生成相同的输出。理想情况下,扩展应该提示用户输入剩余变量,如果在放入命令行之后还有更多剩余变量。所以,如果我运行脚本:

python script.py infile outfile Bob work 

该脚本将仍然提示:

Emotion? 

在命令行中多余的变量将被忽略。我对Python很新,所以虽然这看起来很简单,但我还没有成功使用此插件更新当前的脚本。附上脚本:

import argparse 
from os import path 
import re 

replacements = {} 
pattern = '<<([^>]*)>>' 

def user_replace(match): 
    ## Pull from replacements dict or prompt 
    placeholder = match.group(1) 
    if placeholder in replacements: 
     return replacements[placeholder] 
    ## .setdefault(key, value) returns the value if present, else sets it then returns 
    return replacements.setdefault(placeholder, raw_input('%s? ' % placeholder)) 

def main(): 
    parser = argparse.ArgumentParser() 
    parser.add_argument('infile', type=argparse.FileType('r')) 
    parser.add_argument('outfile', type=argparse.FileType('w')) 
    args = parser.parse_args() 

    matcher = re.compile(pattern) 

    for line in args.infile: 
     new_line = matcher.sub(user_replace, line) 
     args.outfile.write(new_line) 

    args.infile.close() 
    args.outfile.close() 

if __name__ == '__main__': 
    main() 

编辑:上面的输入文件示例是任意的。实际上,输入文件可以具有任意数量的变量,重复任意次数。

回答

3

OK,如果你想动态生成的选项:

parser = argparse.ArgumentParser() 
parser.add_argument('infile', type=argparse.FileType('r')) 
parser.add_argument('outfile', type=argparse.FileType('w')) 

required, extra = parser.parse_known_args() 
infile, outfile = required.infile, required.outfile 

args = re.findall(pattern, infile.read()) 
infile.seek(0) 

parser = argparse.ArgumentParser() 
for arg in args: 
    parser.add_argument('--' + arg.lower()) 

replacements = vars(parser.parse_args(extra)) 

这会给你的所有参数的字典。每个参数值都是列表中的一个字符串。那么你只是做

def user_replace(match): 
    """Pull from replacements dict or prompt""" 
    placeholder = match.group(1) 
    return (replacements[placeholder][0] 
      if placeholder in replacements else 
       raw_input('%s? ' % placeholder)) 

编辑:我编辑了代码在顶部设置参数。这样,参数是可选的,你可以有任何数字。他们的名字将仍然是namelocationemotionreplacements

用户现在可以这样做:

python script.py infile outfile --name Bob --emotion 'extremely frustrated' 

离开了他们想要被提示的,并与引号封闭的空间字符串。

编辑2:编辑顶部,使其动态获取文本文件中的参数。

+0

有什么办法可以循环第一位,所以它适用于任何数量的参数?上面的名字,地点,情绪只是一个例子。实际上,用户可能有更多的参数。 –

+0

我不确定你想要什么,但我用猜测更新了我的答案。 – agf

+0

我的想法是,假设我在输入文件中添加了一个新行: <>现在位于<>。 然后,使用相同的脚本,我可以写四个参数所以它看起来像: “蟒蛇script.py INFILE OUTFILE鲍勃工作失意派对” 然后输出将是: “鲍勃是在工作。 鲍勃感到沮丧 鲍勃现在参加一个派对。“ –

相关问题