代码之家  ›  专栏  ›  技术社区  ›  mar10

Python中递归控制台工具的最佳实践

  •  4
  • mar10  · 技术社区  · 14 年前

    命令行工具的最佳实践(接口和实现)是什么 在目录树中处理选定文件的?

    我举了一个我想到的例子,但我在寻找一个“最佳实践”:

    flipcase foo.txt foo2.txt
    

    可以处理foo.txt文件并将结果保存为foo2.txt。

    flipcase -rv *.txt
    


    -r --recursive 将包含所有子目录。
    -v 在处理时将一些信息打印到stdout。

    我在这个例子中看到的一个问题是 *.txt 论点是 有时被shell(Unix和Vista)扩展,所以我不能应用这种模式
    我想原因是,在Unix上,这样的工具伴随着对 find 但这在Windows上似乎并不常见。这也使得打印一个 最后总结。

    • 必须在Unix、Windows XP、Windows 7和Mac上运行
    • (是的,我知道。但我在寻求一个合理的妥协。 - 而不是 /
    • 不应该像grep那样依赖单独的find命令。
    • 层次结构。
    • OptionParser os.walk
    • 可以处理多种模式,例如。 *.txt,*.html .

    关于设计决策的其他问题:

    • 此工具应返回什么(状态代码)?
    • 自动检测?
    • 是否应支持输出重定向?可配置还是自动检测? 在这种情况下如何处理调试输出?
    • 模式应该是glob语法还是正则表达式?
    • 有支持递归的通用模式语法吗? 也许 吧 recursive:*.txt 在这种情况下 -右
    • 期权 -b --no-backup 选项
    • 应该打印什么状态信息,并对此进行热配置? 默认情况下它应该是详细的并且我们允许 -q 为了安静? 或者总是打印一点 -五 (或 -vv )来促进这个或 到 完全闭嘴?

    我真的不指望得到一个正确的答案,但可能是少数几个 好的示例项目的想法和指针。

    4 回复  |  直到 14 年前
        1
  •  2
  •   FMc TLP    14 年前

    根据我的经验,最好的出发点是构建一个遵循基本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
    
        2
  •  1
  •   loevborg    14 年前

    为了解决您问题中的全局性问题,您列表中的一个奇怪的人实际上支持Windows。UNIX的方法,也是一个很好的方法,就是让shell处理globbing。你只需要一个文件列表。我不知道UNIX工具自己做什么globbing(在这样的基本情况下)。我建议你也不要自己动手,而是依靠贝壳。

    在Windows上,您可以让人们使用带有Cygwin的shell,或者类似的东西。当然,Windows用户通常会避开命令行,因此如果你构建一个GUI,他们也会很高兴。

    那不包括你的钱 -r 开关。但在那里很难。是否向用户提供指定“扩展名为.txt的子目录中的所有文件”的功能?请注意,像ZSH这样的现代shell可以执行递归到目录中的glob,例如:

    rm **/*.tmp
    

    而且,正如你所说,你可以随时使用 find 相反。因此,这里的建议确实需要考虑工具的具体情况。 rsync -右 切换,但是一个假设 flipcase 可能不会。

        3
  •  1
  •   Coding District    14 年前

    在中处理选定文件的工具 目录树?

    另外,我认为你也在寻找这样的东西: http://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html

    我看到的一个问题是 例如,*.txt参数 有时由shell(Unix)扩展 和Vista),所以我不能应用这个 遍历子目录时的模式。

    * 自动展开。我不确定窗户是不是开错了, * 没有展开,所以您可以简单地使用 glob.glob(sys.argv[1])

        4
  •  0
  •   Bite code    14 年前

    递归处理通常使用 os.path.walk ,但是您可以创建自己的版本来使用Python生成器,这对命令行友好得多:管道将在处理时获得输出。这里是 a tested and documented proof of concept .

    使用python3,您不必像它提供的那样去做 os.walk 创造了一个发电机。

    然后,按照FM的建议使用创建CLI接口 optparse .