我正在尝试在Popen中运行这个BASH命令:
find /tmp/mount -type f -name "*.rpmsave" -exec rm -f {} \;
但每次我得到: “找到:stderr中缺少`-exec'\ n”的参数。
python相当于什么?
我天真的方式是:
for (root,files,subdirs) in os.walk('/tmp/mount'):
for file in files:
if '.rpmsave' in file:
os.remove(file)
肯定有更好,更pythonic的方法吗?
答案 0 :(得分:4)
您实际上有两个问题 - 第一,为什么Popen
构造不起作用,第二,如何正确使用os.walk
。 Ned回答了第二个,所以我将解决第一个:你需要知道shell逃逸。 \;
是转义;
,因为Bash通常会将;
解释为分隔两个shell命令,并且不会传递给find
。 (在其他一些shell中,{}
也必须进行转义。)
但是对于Popen
,如果可以避免使用shell,通常不会使用shell。所以,这应该有效:
import subprocess
subprocess.Popen(('find', '/tmp/mount', '-type', 'f',
'-name', '*.rpmsave', '-exec', 'rm', '-f', '{}', ';'))
答案 1 :(得分: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))
答案 2 :(得分:1)
如果你发现自己做了很多这样的事情。这可能是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')]