命令行工具的最佳实践(接口和实现)是什么? 处理目录树中的选定文件?
我举一个想到的例子,但我正在寻找'最佳实践':
flipcase foo.txt foo2.txt
可以处理foo.txt并将结果保存为foo2.txt。
flipcase -rv *.txt
可以处理当前目录中的所有文本文件
-r
或--recursive
将包含所有子目录
-v
会在处理时向stdout打印一些信息。
我在这个例子中看到的一个问题是,*.txt
参数是
有时由shell(Unix和Vista)扩展,所以我无法应用这种模式
走路子目录时。
我想原因是,在Unix上,这些工具与find
的调用相结合,
但这似乎并不常见于Windows。它也使得打印难以打印
最后总结。
要求:
-
而不是/
即可。)OptionParser
和os.walk
。*.txt,*.html
。有关设计决策的其他问题:
recursive:*.txt
在这种情况下,-r
选项不是必需的。-b
,或者更确切地说是备份,并添加--no-backup
选项-q
安静吗?
或者总是打印一点,并允许-v
(或-vv
)提升此值或-q
为
完全闭嘴?我真的不希望得到一个正确答案,但可能是少数 对优秀样本项目的想法和指示。
答案 0 :(得分: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
答案 1 :(得分:1)
最佳做法是什么(界面 和实现)命令行 处理所选文件的工具 目录树?
在实现命令行工具时,我认为没有单一的标准或“最佳实践”。虽然,通过查看和试验像GNU coreutils这样的精心构建的工具,您将获得许多见解。
另外,我认为你也在寻找类似的东西:http://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html
阅读和试验Unix的方法实际上解决了许多关于设计决策的问题。
我看到这个问题 例如,* .txt参数是 有时由shell扩展(Unix 和Vista),所以我不能应用这个 走路子目录时的模式。
在Unix中,*
会自动展开。我不确定Windows,但如果我没有弄错,*
没有扩展,所以你可以简单地使用glob.glob(sys.argv[1])
。 Unix的解决方法是逃避通配符,但必须有更好的方法。
答案 2 :(得分:1)
要解决问题的全局部分,列表中的奇怪人物确实支持Windows。 UNIX方式,也是一种好方法,让shell处理globbing。你只需要一个文件列表。我知道没有UNIX工具它自己的globbing(在这样的基本情况下)。我建议你自己也不要这样做,但要依靠shell。
在Windows上,您可以引用人们使用带有Cygwin的shell,或类似的东西。当然,Windows用户通常会避开命令行,所以如果你构建一个GUI,他们也会很开心。
这不包括您的-r
转换。但那里很难。您是否希望向用户提供指定“具有扩展名.txt的子目录中的所有文件”的能力?请注意,像ZSH这样的现代shell可以执行递归到目录的globs,例如:
rm **/*.tmp
并且,正如您所说,您始终可以使用find
。因此,这里的推荐确实需要考虑您工具的细节。 rsync
可以实现自己的-r
转换,但假设的flipcase
可能不会。
答案 3 :(得分:0)
递归处理通常使用os.path.walk完成,但您可以创建自己的版本以使用Python生成器,它更加命令行友好:管道将在处理时获得输出。这是a tested and documented proof of concept。
使用Python 3,您不必这样做,因为它提供了创建生成器的os.walk。
然后,按照FM建议使用optparse创建CLI界面。