2011-07-22 62 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鮑勃工作失意派對」 然後輸出將是: 「鮑勃是在工作。 鮑勃感到沮喪 鮑勃現在參加一個派對。「 –

相關問題