1

我使用 find 和 wc 来获取使用管道的总 LOC。

find . -name "*.cpp" -print | xargs wc

  44     109     896 ./main.cpp
 ...
 288    1015    8319 ./src/util/util.cpp
 733    2180   21494 total

我需要使用 python 自动获取 LOC,我将运行 find .. | xargs 命令多次,得到结果并处理得到总 LOC。

如何在 Python 中通过管道执行命令?我试过这个,但它什么也没返回。

import subprocess
p = subprocess.Popen(['find', '.', '-name', "*.cc", "-print", "|", "xargs", "wc"], 
    stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE)
out, err = p.communicate()
print out

添加

在 konishchev 的提示下,我可以让它发挥作用。

p1 = Popen(['find', '.', '-name', "*.cc", "-print"], stdout=PIPE)
p2 = Popen(["xargs", "wc"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
print output
4

2 回答 2

1

您必须像这里描述的那样连接两个 Popen 对象。

但我想推荐psh module,因为它更容易用于此类事情。

于 2013-06-20T19:26:48.440 回答
1

管道是一个外壳函数。因此,您的Popen通话需要shell=True它。否则你| wc将被传递给find,它不知道如何处理它(并且可能会发送一个错误到err......你没有打印)。

但是为什么要掏空呢?只需在 Python 中做所有这些事情(例如os.walk替换find)它会更容易阅读和维护。就像是:

import os, re
for dirpath, dirnames, filenames in os.walk(rootpath):
    for filename in filenames:
        if filename.endswith(".cc"):
            with open(os.path.join(dirpath, filename)) as infile:
                text = infile.read()
                chars = len(text)
                lines = sum(1 for x in re.finditer(r"\n", text))
                lines += not text.endswith("\n")  # count last line if no newline
                words = sum(1 for x in re.finditer(r"\w+", text))
                # do whatever with these...
于 2013-06-20T18:59:15.937 回答