1

我想从 python 程序中执行这一系列命令。

wc -l <(comm -12 <(sort file1.txt) <(sort file2.txt))

我在以下方面取得了成功:

sort_a = Popen("sort file1.txt", shell=False, stdout=PIPE)
count = Popen(["wc", "-l"], shell=False, stdout=PIPE, stdin=sort_a.stdin)

我无法弄清楚他如何将多个标准输出重定向到 comm -12 的标准输入。

我想也许:

compare = Popen(["comm", "-12"], shell=False, stdout=PIPE, stdin=[sort_a.stdin, sort_b.stdin])

想法?

4

1 回答 1

1

首先,让我们看看 shell 的<(command)命令替换是如何工作的。该命令以指向新创建的管道的输出开始。然后管道在命令行上作为文件名传递给外部命令。

例如:

$ echo wc -w <(date)
wc -l /dev/fd/63

显示 shell 从date输出到管道开始,然后将/dev/fd/63引用文件描述符 63 处的新管道的伪文件作为实际命令行参数传递。


为了在 Python 中获得相同的行为,我们可以实现相同的东西:

from subprocess import *

date = Popen(['date'], stdout=PIPE)
Popen(["wc", "-w", "/dev/fd/%d" % date.stdout.fileno()])

打印

6 /dev/fd/3

你可以写一个类来使它更容易做。这使用一个with语句并临时保留对每个生成的进程的引用,否则当进程对象被垃圾收集时管道将关闭。

from subprocess import *

class CommandSubstituter(object):
    def __init__(self):
        self._procs = []

    def __enter__(self):
        return self

    def __exit__(self, *exc_info):
        pass

    def subst(self, *args, **kwargs):
        proc = Popen(*args, stdout=PIPE, **kwargs)
        self._procs.append(proc)
        return "/dev/fd/%d" % proc.stdout.fileno()

with CommandSubstituter() as c:
    Popen(['wc', '-l',
           c.subst(['comm', '-12',
                    c.subst(['sort', 'file1.txt']),
                    c.subst(['sort', 'file2.txt'])])])
于 2013-01-22T17:31:41.253 回答