2010-09-05 54 views
4

處理目錄樹中選定文件的命令行工具 的最佳實踐(界面和實現)是什麼?Python中遞歸控制檯工具的最佳實踐

我給那個在我腦海中的例子,但是我正在尋找一個「最佳實踐」:

flipcase foo.txt foo2.txt 

可以處理foo.txt的,並保存結果作爲foo2.txt。

flipcase -rv *.txt 

可以處理當前目錄中的所有文本文件。
-r--recursive將包括所有子目錄。
-v將在處理時打印一些信息到標準輸出。

的一個問題,我用這個例子中看到的是,該*.txt參數 有時由shell(Unix和Vista)的擴展,所以走子目錄時,我不能應用此模式 。
我想原因是,在Unix上這些工具是通過調用find, 來實現的,但這在Windows中似乎不常見。這也使得最後難以打印摘要。

要求:

  • 必須在UNIX,Windows XP,Windows 7和Mac的
  • 運行應該遵循這些平臺上的共同約定。 (是的,我知道,但我正在尋找一個合理的妥協。 例如它的確定在Windows上使用-而不是/
  • 不應單獨依靠find命令,如grep一樣。
  • 必須適用於目錄 層級中的單個文件,文件模式和模式。
  • 應該使用標準的Python庫,例如OptionParseros.walk
  • 可以處理多種圖案,例如, *.txt,*.html

設計決定的其他問題:

  • 應該採取什麼這個工具回報(狀態代碼)?
  • 這個工具應該使用哪個ctrl-keys,以什麼方式處理?
  • 應該支持stdin而不是單個文件嗎?可配置或 自動檢測?
  • 應該支持輸出重定向嗎?可配置或自動檢測? 在這種情況下如何處理調試輸出?
  • 模式應該是glob語法還是正則表達式?
  • 是否有支持遞歸的通用模式語法? 也許recursive:*.txt 在這種情況下,-r選項不會是必要的。
  • 創建修改文件備份的最佳做法是什麼? 選項-b,或者更確切地說是在默認情況下進行備份並添加--no-backup選項
  • 對於單個文件,應該可以指定目標文件名。怎麼樣?
  • 應該打印什麼狀態信息,並熱配置? 默認情況下應該是冗長的,我們允許-q安靜嗎? 或者總是打印一點點,並允許-v(或-vv)提高這個或-q到 完全閉嘴?

我真的不希望得到一個單一的正確答案,但可能是少數 想法和指向良好示例項目。

回答

2

根據我的經驗,最好的出發點是構建一個遵循基本Unix原則的工具 - 即從標準輸入讀取並寫入標準輸出。這使人們靈活地使用您的工具:

flipcase input.txt > output.txt 
othercommand | flipcase > output.txt 
flipcase | othercommand > ouput.txt 
flipcase input1.txt input2.txt > output.txt 

下一個功能可能是就地編輯:

# Modify input files directly. 
flipcase -i input.txt 

# Create backup copies before modifying originals. 
flipcase -i --backup-suffix '_BAK' input.txt 
flipcase -i --backup-prefix 'BAK_' input.txt 

# Regex for power users. 
flipcase -i --backup-regex 's/foo/bar/' input.txt 

在詳細模式下,該工具不應該寫標準輸出,因爲這會與上述核心原則相沖突。它應該寫入標準錯誤或用戶定義的日誌文件。

flipcase -v   input.txt > output.txt 
flipcase -v log.txt input.txt > output.txt 

之後,添加遞歸行爲。這裏的方向不太明確,但我會拋出一些想法。在典型的遞歸情況下,程序的參數可能是目錄,用戶需要提供額外的選項來定義各種類型的過濾行爲(即要處理的文件類型)。

flipcase -r -i --backup-suffix '_BAK' --filter-glob '*.txt' dir1 dir2 
flipcase -r -i --backup-suffix '_BAK' --filter-glob '*.txt' --filter-glob 'log*.dat' dir 
flipcase -r -i --backup-suffix '_BAK' --filter-regex 'log\w+\.(txt|log)$' dir1 dir2 

# Don't do in-place editing. Instead create new files within the structure. 
flipcase -r --newname-suffix '_NEW'    --filter-glob '*.txt' dir1 dir2 
flipcase -r --newname-regex 's/\.txt$/_new.txt/' --filter-glob '*.txt' dir1 dir2 

# Create the backups or the new files in a parallel directory 
# structure rather than within the original structure. 
flipcase -r -i --backup-tree 'backup_dir' --filter-glob '*.txt' dir1 dir2 
flipcase -r -i --new-tree 'newfiles_dir' --filter-glob '*.txt' dir1 dir2 
+0

感謝您的全面輸入! – mar10 2010-09-06 21:20:39

+0

您使用的選項名稱是「common」,即是否有使用它們的衆所周知的工具? – mar10 2010-09-06 21:27:16

+0

@ mar10僅在某些情況下。 '-v'和'-r'選項通常用於詳細和遞歸。 '-i'選項反映了我的Perl背景,它用於就地文件編輯(Perl可能從'sed'繼承了這個約定)。我提出的更長的選擇只是粗略的想法。您可能需要查看其他遞歸Unix工具,瞭解有關選項命名的想法:'find','rsync',或許還有其他。 – FMc 2010-09-06 23:10:57

1

什麼是一個命令行 工具,流程 目錄樹中選擇文件的最佳實踐(接口 和實現)?

當涉及到命令行工具的實現時,我不認爲有一個標準或「最佳實踐」。儘管如此,通過查看和試驗諸如GNU coreutils等完善工具,您將獲得很多見解。

另外,我認爲你在尋找這樣的事情還有:http://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html

閱讀和試驗有關執行此操作的Unix的實際解決了許多您的問題有關的設計決策。

的一個問題,我這個 例子看到的是,是,* .TXT說法是 有時殼(Unix的 和Vista)擴大,所以走子目錄時我無法將此 模式。

在Unix中,*會自動展開。我不確定Windows,但如果我沒有錯,*不擴展,所以你可以簡單地使用glob.glob(sys.argv[1])。 Unix的解決方法是逃避通配符,但必須有更好的方法。

+0

感謝您的指針,GNU是一個很好的參考。 (順便說一下,Vista似乎擴大了*,但據我所知,Windows的舊版本沒有) – mar10 2010-09-06 21:37:57

0

遞歸處理通常使用os.path.walk來完成,但是您可以創建自己的版本以使用Python生成器,這對命令行更友好:管道將在處理輸出時獲取輸出。這裏是a tested and documented proof of concept

使用Python 3,您不必這樣做,因爲它提供了創建生成器的os.walk

然後,按照FM建議使用optparse創建CLI界面。

1

爲了解決您問題中的問題,列表中的奇怪人物確實支持Windows。 UNIX方式,也是一種很好的方法,就是讓shell處理這個通配符。你只是得到一個文件列表。我知道沒有UNIX工具它自己的globbing(在這種基本情況下)。我建議你也不要自己動手,但要依靠外殼。

在Windows上,您可以引用人們使用Cygwin的shell或類似的東西。當然,Windows用戶通常會避開命令行,所以如果你構建一個GUI,他們也會很開心。

這並不包括您的-r開關。但在那裏變得困難。你想提供給用戶指定「擴展名爲.txt的子目錄中的所有文件」嗎?需要注意的是像ZSH現代shell能做到這一點遞歸到目錄水珠,如:

rm **/*.tmp 

,正如你說的,你可以隨時使用find代替。因此,這裏的建議確實需要考慮工具的具體情況。 rsync受益於實施自己的-r交換機,但假設的flipcase可能不會。

+0

我想對於大多數Windows用戶來說,要求cygwin太多了。我喜歡'rm * */* .tmp'語法。但這似乎很難實現,由於shell globbing(考慮到我不想依賴像ZSH這樣的特定shell) – mar10 2010-09-06 21:34:03