在 python 中迭代 linux 排序输出

我无法找到使用 linuxsort命令作为 python 脚本输入的解决方案。


例如我想迭代结果sort -mk1 <(cat file1.txt) <(cat file2.txt))


通常我会使用andPopen迭代它,例如:nextstdout.readline()


import os

import subprocess


class Reader():

    def __init__(self):

        self.proc = subprocess.Popen(['sort -mk1', '<(', 'cat file1.txt', ')', '<(', 'cat file2.txt', ')'], stdout=subprocess.PIPE)


    def __iter__(self):

        return self


    def __next__(self):

        while True:

            line = self.proc.stdout.readline()

            if not line:

                raise StopIteration

            return line



p = Reader()

for line in p:

    # only print certain lines based on some filter 

有了上面的内容,我会得到一个错误:No such file or directory: 'sort -mk1'


经过一些研究后,我想我不能使用 Popen,而必须使用os.execl来利用bin/bash


所以现在我尝试以下:


import os

import subprocess


class Reader():

    def __init__(self):

        self.proc = os.execl('/bin/bash', '/bin/bash', '-c', 'set -o pipefail; sort -mk1 <(cat file1.txt) <(cat file2.txt)')


    def __iter__(self):

        return self


    def __next__(self):

        while True:

            line = self.proc.stdout.readline()

            if not line:

                raise StopIteration

            return line



p = Reader()

for line in p:

    # only print certain lines based on some filter 

问题在于它实际上立即打印了所有行。我想一种解决方案是将其结果通过管道传输到一个文件,然后在 python 中迭代该文件。但我真的不想将其保存到文件中然后对其进行过滤,似乎没有必要。是的,我可以使用其他 linux 命令,例如awk,但我想使用 python 进行进一步处理。

所以问题是:

  1. 有没有一种方法可以使解决方案一并Popen发挥作用?

  2. 如何迭代sort使用第二个解决方案的输出?


喵喵时光机
浏览 112回答 3
3回答

慕容3067478

如果你想使用 shell 功能,你必须使用shell=True. 如果你想使用 Bash 功能,你必须确保你运行的 shell 是 Bash。&nbsp; &nbsp; &nbsp; &nbsp; self.proc = subprocess.Popen(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'sort -mk1 <(cat file1.txt) <(cat file2.txt)',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stdout=subprocess.PIPE,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shell=True,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; executable='/bin/bash')请注意and Friendsshell=True的第一个参数Popen是单个字符串(反之亦然;如果没有,则shell=True必须自己将命令行解析为标记)。当然,cats 是无用的,但是如果您将它们替换为 shell 可以轻松优雅地执行并且无法轻松地用本机 Python 代码替换的内容,那么这可能是正确的选择。简而言之,<(command)就是Bash进程的替代;shell 将command在子进程中运行,并将参数替换为进程生成输出的打开文件句柄的设备名称。所以sort会看到类似的东西sort -mk /dev/fd/63 /dev/fd/64其中/dev/fd/63是第一个命令的输出可用的管道,并且/dev/fd/64是另一个命令的标准输出的读取端。

芜湖不芜

你的脚本中有很多问题。首先,Popen由于以下几个原因,您将无法工作:第一个参数应该是要运行的命令,而您传递了sort -mk并且没有这样的文件。您应该简单地传递sort, 并-mk作为参数传递。进程替换<( command )是由 shell 处理的事情,它正在执行一些操作,例如运行命令、创建 FIFO 并将其替换为 FIFO 的名称。直接将这些传递给sort是行不通的。&nbsp;sort可能只会将其视为<(文件名。您的第二种使用方式os.exec*也不起作用,因为os.exec*它将取代您当前的流程。因此,它永远不会继续执行 Python 脚本中的下一条语句。就您而言,似乎没有理由使用流程替换。为什么你不能简单地做一些类似的事情subprocess.Popen(['sort', '-mk', 'filename1', 'filename2'])?

拉丁的传说

我不明白你为什么要这样做 sort -mk1 $(cat file),sort 可以对文件进行操作。查看check_output。这会让你的生活变得简单output=subprocess.check_output('ls')for line in output:&nbsp; &nbsp; print(line)当然,您必须处理异常,手册页有详细信息
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python