为了账号安全,请及时绑定邮箱和手机立即绑定

在 python 中迭代 linux 排序输出

在 python 中迭代 linux 排序输出

喵喵时光机 2023-10-05 16:32:37
我无法找到使用 linuxsort命令作为 python 脚本输入的解决方案。例如我想迭代结果sort -mk1 <(cat file1.txt) <(cat file2.txt))通常我会使用andPopen迭代它,例如:nextstdout.readline()import osimport subprocessclass 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 linep = 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 osimport subprocessclass 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 linep = Reader()for line in p:    # only print certain lines based on some filter 问题在于它实际上立即打印了所有行。我想一种解决方案是将其结果通过管道传输到一个文件,然后在 python 中迭代该文件。但我真的不想将其保存到文件中然后对其进行过滤,似乎没有必要。是的,我可以使用其他 linux 命令,例如awk,但我想使用 python 进行进一步处理。所以问题是:有没有一种方法可以使解决方案一并Popen发挥作用?如何迭代sort使用第二个解决方案的输出?
查看完整描述

3 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

如果你想使用 shell 功能,你必须使用shell=True. 如果你想使用 Bash 功能,你必须确保你运行的 shell 是 Bash。


        self.proc = subprocess.Popen(

            'sort -mk1 <(cat file1.txt) <(cat file2.txt)',

            stdout=subprocess.PIPE,

            shell=True,

            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是另一个命令的标准输出的读取端。


查看完整回答
反对 回复 2023-10-05
?
芜湖不芜

TA贡献1796条经验 获得超7个赞

你的脚本中有很多问题。

首先,Popen由于以下几个原因,您将无法工作:

  1. 第一个参数应该是要运行的命令,而您传递了sort -mk并且没有这样的文件。您应该简单地传递sort, 并-mk作为参数传递。

  2. 进程替换<( command )是由 shell 处理的事情,它正在执行一些操作,例如运行命令、创建 FIFO 并将其替换为 FIFO 的名称。直接将这些传递给sort是行不通的。 sort可能只会将其视为<(文件名。

您的第二种使用方式os.exec*也不起作用,因为os.exec*它将取代您当前的流程。因此,它永远不会继续执行 Python 脚本中的下一条语句。

就您而言,似乎没有理由使用流程替换。为什么你不能简单地做一些类似的事情subprocess.Popen(['sort', '-mk', 'filename1', 'filename2'])


查看完整回答
反对 回复 2023-10-05
?
拉丁的传说

TA贡献1789条经验 获得超8个赞

我不明白你为什么要这样做 sort -mk1 $(cat file),sort 可以对文件进行操作。查看check_output。这会让你的生活变得简单


output=subprocess.check_output('ls')

for line in output:

    print(line)

当然,您必须处理异常,手册页有详细信息


查看完整回答
反对 回复 2023-10-05
  • 3 回答
  • 0 关注
  • 111 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信