【问题标题】:Python equivalent to find -execPython 等价于 find -exec
【发布时间】:2013-02-08 17:23:18
【问题描述】:

我正在尝试在 Popen 中运行此 BASH 命令:

find /tmp/mount -type f -name "*.rpmsave" -exec rm -f {} \;

但每次我得到: “查找:缺少 `-exec'\n 的参数”在标准错误中。

python 相当于什么?

我的幼稚做法是:

for (root,files,subdirs) in os.walk('/tmp/mount'):
    for file in files:
        if '.rpmsave' in file:
            os.remove(file)

肯定有更好、更 Python 的方式来做这件事吗?

【问题讨论】:

    标签: python popen3


    【解决方案1】:

    您实际上有两个问题 - 首先,为什么您的 Popen 构造不起作用,第二,如何正确使用 os.walk。 Ned 回答了第二个问题,所以我将解决第一个问题:您需要注意 shell 转义。 \; 是转义的;,因为通常; 会被 Bash 解释为分隔两个 shell 命令,并且不会传递给 find。 (在其他一些 shell 中,{} 也必须被转义。)

    但是对于Popen,如果可以避免的话,您通常不想使用外壳。所以,这应该工作:

    import subprocess
    
    subprocess.Popen(('find', '/tmp/mount', '-type', 'f',
                      '-name', '*.rpmsave', '-exec', 'rm', '-f', '{}', ';'))
    

    【讨论】:

    • 我想你是对的,我尝试过命令列表的每一种组合,因为我过去有使用 Popen 命令的经验,但是我不了解我实际使用的 find 命令的细节。这成功了,在我的具体情况下,它是比 os.walk 更好的解决方案。谢谢。
    • 您可以使用'rm', '-f', '--', '{}', '+' 来允许以- 开头的文件,并一次将多个文件名传递给rm
    【解决方案2】:

    你所拥有的基本上就是做到这一点的方法。您正在协调三件不同的事情:1) 遍历树,2) 仅对 .rpmsave 文件进行操作,以及 3) 删除这些文件。您会在哪里找到可以在本地完成所有这些操作而无需拼写出来的东西? Bash 命令和 Python 代码的复杂度大致相同,这不足为奇。

    但是你必须修复你的代码,像这样:

    for root,files,subdirs in os.walk('/tmp/mount'):
        for file in files:
            if file.endswith('.rpmsave'):
                os.remove(os.path.join(root, file))
    

    【讨论】:

    • 交换filessubdirs
    【解决方案3】:

    如果您发现自己经常做这些事情。这可能是 os.walk 的有用包装器:

    def files(dir):
       # note you have subdirs and files flipped in your code
       for root,subdirs,files in os.walk(dir):
          for file in files:
             yield os.path.join(root,file)
    

    删除目录中具有特定扩展名的一堆文件:

    [os.remove(file) for file in files(directory) if file.endswith('.extension')]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      • 2010-10-12
      • 2012-08-16
      • 2011-02-04
      • 2011-02-11
      • 2015-01-25
      相关资源
      最近更新 更多