2016-03-08 40 views
0

我正在將shell腳本轉換爲Python。是否可以使用argparse來處理複雜的混合和匹配命令行參數(無選項)?

shell腳本支持這樣的參數。

在「命令」部分列出
Usage: foo [-h] [-v] [COMMAND] [COMMAND_ARG]... 

One or more of the following commands may be specified in the same 
command line invocation of this script. 

Commands: 
    print   Print lines in CSV. 
    search PATTERN Print only lines that match PATTERN. 
    remove PATTERN Remove all lines that match PATTERN. 
    convert   Convert CSV file to XLS file. 
    limit N   Show a maximum of N results (default 10). 
    all    Do not limit lines. 

Options: 
    -h, --help  Show help. 
    -v, --version Show version. 

一個或多個參數可以被混合和匹配 但它們中的一些是相互排斥的。

例如,以下所有內容都是有效的命令行調用。

# Prints 10 lines from CSV 
foo print 

# Prints 3 lines from CSV 
foo print limit 3 
foo limit 3 print 

# Prints all lines from CSV 
foo print all 
foo all print 

# Converts 10 lines from CSV into XLS 
foo convert 

# Converts 3 lines from CSV into XLS 
foo limit 3 convert 
foo convert limit 3 

# Search for the word "foo" in CSV and print 3 such lines 
foo search "\<foo\>" limit 3 
foo limit 3 search "\<foo\>" 

然而,printsearchremoveconvert是相互 排斥。所以以下是無效的。

foo print convert 
foo search "\<foo\>" remove "\<foo\>" 

是否可以處理命令行參數,像這些用 ​​?或者我最好是循環利用sys.argv我自己, 用我自己的代碼處理這些情況,這也意味着我有 負責更新幫助消息和任何必要的驗證 每當支持的參數列表發生變化時?

注意:我不想依賴​​模塊的任何內部實現來實現此目的。我只想依靠公開記錄的​​的API。如果用公開記錄的API​​來解決這個問題是不可能的,那麼這很好,那就是答案。在這種情況下,我會自己處理命令行參數,通過循環遍歷sys.argv類似於shell腳本通過循環遍歷"[email protected]"來處理參數。

回答

1

其中--limit--all是可選項的變體,其餘均爲適合​​的子分析器。

不能運行多個子分析器(例如printlimit)而沒有一些嚴重的卷積。 Plus limitall在概念上是非常不同的論點。其他人是命令 - 做這樣的事情 - 這樣的。 limitall是修飾符。

待辦事項limitall與所有其他人,或者只是printsearch工作。對於那些子分析者來說,它們可能更有意義。

另請注意,​​的一大優點是它會生成使用情況,幫助和錯誤消息。當你做一些不尋常的事情時,你需要考慮這些信息。你如何明確告訴你的用戶他們可以使用limitprint而不是convert?或者他們不能同時使用limitall;或者一個壓倒另一個。

但是,如果你被這些名稱/標誌卡住,並且不能添加--,那麼請不要打擾​​。不要打擾改變已經有效的東西。

​​(和optparsegetopt)中的基本原理是使用標記字符串(' - '),您希望將內容與動作匹配,並按順序處理其餘部分。​​希望根據位置解析您的字符串,而不是內容。

0

它可以主要處理這個,只是不太像你這樣做。您將使用subcommands/subparsers進行打印,搜索,刪除和轉換,並將其他命令(頂層命令的真正選項)定義爲開關,如果它們對所有命令通用,或者在頂級解析器上各個子分析器/子命令(如果它們不常見)。

現在,在這種特殊情況下,好像你甚至不必爲每個子獨特的行爲,所以你可能只是一個位置參數脫身,兩個開關:

parser = argparse.ArgumentParser() 
parser.add_argument('action', choices=('print', 'search', 'remove', 'convert') 
parsecount = parser.add_mutually_exclusive_group() 
parsecount.add_argument('--all', dest='limit', action='store_const', const=None) 
parsecount.add_argument('--limit', type=int) 
parser.set_defaults(limit=10) 

的位置action如果需要,可以將參數更改爲單個子分析器,但在這種情況下,似乎所有可能的命令都允許alllimit

+0

通過將'all'和'limit'轉換爲'--all'和'--limit'來改變命令行界面,我不能這樣做,因爲用戶已經依靠'all'和'limit'作爲參數。我的問題是,命令行界面必須保持不變。因此,我需要決定是否應該使用'argparse',或者如果我應該編寫我的代碼來處理命令行參數。 –

+0

好的,那麼不,不是你可以直接用'argparse'完成的事情。我確實已經說清楚它是「大部分」,而不是「完全」。 – ShadowRanger

相關問題