2015-02-24 70 views
1

我有類似下面的列表:如何代表bash命令的元素,新的列表特色的一個列表的元素結合等號

commandOptionsAndArguments = ['myBigTool', '--num-callers', '30', '--leak-check', 'full', '--tool', 'memcheck', '--suppressions', 'etc/valgrind-root.supp', '--suppressions', 'Gaudi.supp/Gaudi.supp', '--suppressions', 'oracleDB.supp', '--suppressions', 'valgrindRTT.supp', '--suppressions', 'root.supp/root.supp', '--mySpecialFlag', '$(which python)', '$(which athena.py)', 'athenaConf.pkl'] 

該列表由bash命令的元素具有選項,如果他們有他們各自的論點。我想將其轉換爲以下列表:

commandOptions = ['myBigTool', '--num-callers=30', '--leak-check=full', '--tool=memcheck', '--suppressions=etc/valgrind-root.supp', '--suppressions=Gaudi.supp/Gaudi.supp', '--suppressions=oracleDB.supp', '--suppressions=valgrindRTT.supp', '--suppressions=root.supp/root.supp', '--mySpecialFlag', '$(which python)', '$(which athena.py)', 'athenaConf.pkl'] 

這個新的列表包含的選項,如果他們有他們,用等號進入新的元素結合各自的論點。下一步將是要麼使用子進程來執行該命令或將其轉換爲使用的字符串os.system

" ".join(commandOptions) 
# 'myBigTool --num-callers=30 --leak-check=full --tool=memcheck --suppressions=etc/valgrind-root.supp --suppressions=Gaudi.supp/Gaudi.supp --suppressions=oracleDB.supp --suppressions=valgrindRTT.supp --suppressions=root.supp/root.supp --mySpecialFlag $(which python) $(which athena.py) athenaConf.pkl' 

我的問題是:我如何在一個穩健的方式列表commandOptionsAndArguments更改到列表commandOptions ,用參數檢測兩個選項並且沒有適當的參數?我不確定我應該用什麼詞來描述使用等號的方式來指定參數。而不是用空格命令選項)

+1

您如何期望在說--suppressions和--mySpecialFlag之間做出區別?基於格式(破折號分隔vs CamelCase)? – d6bels 2015-02-24 13:37:12

+0

是的,這是一個問題,我正在尋找建議。你會建議一個合理的方法嗎? – d3pd 2015-02-24 13:44:38

+0

我沒有看到任何簡單和優雅的東西,可能取決於你如何建立這個列表或你可以改變多少。 – d6bels 2015-02-24 13:50:41

回答

1

你可以在這裏使用re模塊。

>>> commandOptionsAndArguments = ['myBigTool', '--num-callers', '30', '--leak-check', 'full', '--tool', 'memcheck', '--suppressions', 'etc/valgrind-root.supp', '--suppressions', 'Gaudi.supp/Gaudi.supp', '--suppressions', 'oracleDB.supp', '--suppressions', 'valgrindRTT.supp', '--suppressions', 'root.supp/root.supp', '--mySpecialFlag', '$(which python)', '$(which athena.py)', 'athenaConf.pkl'] 
>>> re.split(r'\s+(?![^()]*\))', re.sub(r'(--\S+)\s+(\w\S+)', r'\1=\2', ' '.join(commandOptionsAndArguments))) 
['myBigTool', '--num-callers=30', '--leak-check=full', '--tool=memcheck', '--suppressions=etc/valgrind-root.supp', '--suppressions=Gaudi.supp/Gaudi.supp', '--suppressions=oracleDB.supp', '--suppressions=valgrindRTT.supp', '--suppressions=root.supp/root.supp', '--mySpecialFlag', '$(which python)', '$(which athena.py)', 'athenaConf.pkl'] 

說明:

  • ' '.join(commandOptionsAndArguments)加入在給定列表中的所有元素與作爲分隔符的空間。

  • 而這種替換其存在於與--啓動字和與=符號(其與字字符開始)字之間=的空間。因此它不會取代--mySpecialFlag$(which python)之間的空格。

    re.sub(r'(--\S+)\s+(\w\S+)', r'\1=\2', ' '.join(commandOptionsAndArguments)) 
    
  • 最後這r'\s+(?![^()]*\))'匹配一個或多個空間中不存在的()括號內。通過根據匹配的空格分割結果字符串將會給你所需的輸出。

+0

哇,那是怎麼工作的?它是如何應對這種尷尬的無爭議的標誌選項? – d3pd 2015-02-24 14:00:09

+0

非常感謝您解釋這是如何工作的,特別關注正則表達式。我真的必須熟悉它... – d3pd 2015-02-24 14:31:38

1

你可以用切片:

>>> [commandOptionsAndArguments[0]]+['='.join(commandOptionsAndArguments[1:][i:i+2]) for i in range(0,len(commandOptionsAndArguments)-1,2)] 
['myBigTool', '--num-callers=30', '--leak-check=full', '--tool=memcheck', '--suppressions=etc/valgrind-root.supp', '--suppressions=Gaudi.supp/Gaudi.supp', '--suppressions=oracleDB.supp', '--suppressions=valgrindRTT.supp', '--suppressions=root.supp/root.supp', '--mySpecialFlag=$(which python)', '$(which athena.py)=athenaConf.pkl'] 
>>> 
+0

非常感謝您的建議。結合切片和列表理解的方法非常高效,但它不能處理沒有參數的選項。沒有參數的示例選項是'''--- mySpecialFlag'''。在它之後,你可以看到有一個可執行文件'''myBigTool''(Valgrind的佔位符)運行的程序。 – d3pd 2015-02-24 13:48:03

+0

@ d3pd不客氣!不幸的是我想念你的編輯!但很高興你罰款解決方案! – Kasramvd 2015-02-24 17:26:40

相關問題