Python 调用外部egrep和less时,子进程非常慢
我正在尝试构建一个python脚本,它将允许我在egrep-v属性上动态构建,并将输出导入更少(或更多)属性Python 调用外部egrep和less时,子进程非常慢,python,grep,subprocess,less-unix,Python,Grep,Subprocess,Less Unix,我正在尝试构建一个python脚本,它将允许我在egrep-v属性上动态构建,并将输出导入更少(或更多)属性 我希望使用external egrep+less的原因是因为我正在处理的文件是非常大的文本文件(500MB+)。首先将它们读入一个列表,然后通过Python以本机方式进行处理,这是非常缓慢的。 然而,当我使用os.system或SUBSPROCESS.call时,在我想要退出较少的输出并返回python代码时,一切都非常缓慢。 我的代码应该是这样工作的: 1. ./myless.p
我希望使用external egrep+less的原因是因为我正在处理的文件是非常大的文本文件(500MB+)。首先将它们读入一个列表,然后通过Python以本机方式进行处理,这是非常缓慢的。
然而,当我使用os.system或SUBSPROCESS.call时,在我想要退出较少的输出并返回python代码时,一切都非常缓慢。
我的代码应该是这样工作的:
1. ./myless.py消息\u 500MB.txt
2.Less-显示消息\u 500MB.txt的FRX输出(完整文件)。
3.当我按“q”退出less-FRX时,python代码应该接管并显示提示,提示用户输入要排除的文本。用户输入它,我将其添加到列表中
4.我的python代码构建了egrep-v“exclude1”,并将输出传输到less
5.用户重复步骤3并输入另一个要排除的内容
6.现在,我的python代码调用egrep-v'exclude1 | exclude2'消息_500MB.txt | less-FRX
7.并且该过程将继续
但是,这并不像预期的那样有效。
*在我的Mac电脑上,当用户按q退出less-FRX时,需要几秒钟才能显示原始输入提示
*在Linux机器上,我收到了大量的“egrep:writing output:break pipe”
*如果在less-FRX中(仅限linux),我按CTRL+C,出于某种原因退出less-FRX会快得多(如预期的那样)。在Mac上,我的python程序中断
以下是我的代码示例:
excluded = list()
myInput = ''
while myInput != 'q':
grepText = '|'.join(excluded)
if grepText == '':
command = 'egrep "" ' + file + ' | less -FRX'
else:
command = 'egrep -v "' + grepText + '" ' + file + ' | less -FRX'
subprocess.call(command, shell=True)
myInput = raw_input('Enter text to exclude, q to exit, # to see what is excluded: ')
excluded.append(myInput)
任何帮助都将不胜感激事实上,我知道问题出在哪里了
我对在Linux上运行脚本时出现的错误做了一些研究(“egrep:writing output:break pipe”),这让我找到了答案:
问题是当我使用egrep-v'xyz'file时,退出的次数减少了,子进程仍然继续在大文件(500MB+)上运行egrep,这需要一段时间
相应地,即使在第二个程序(less)退出后,子流程也会分别运行两个程序并运行第一个程序(egrep)
为了正确地解决我的问题,我使用了如下方法:
command = 'egrep -v "something" <filename>'
cmd2 = ('less', '-FRX')
egrep = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
subprocess.check_call(cmd2, stdin=egrep.stdout)
egrep.terminate()
command='egrep-v“某物”'
cmd2=('less','-FRX')
egrep=subprocess.Popen(命令,shell=True,stdout=subprocess.PIPE)
子进程检查调用(cmd2,stdin=egrep.stdout)
egrep.terminate()
通过将第一个进程导出到第二个进程stdin中,我现在可以在退出更少时立即终止egrep,现在我的python脚本正在运行:)干杯,
Milos注意:
.terminate()
终止shell进程(/bin/sh
),孙子进程可能会继续运行。看见或者更好的方法是,不使用shell直接运行grep
。您还应关闭管道,以避免fd泄漏。再见,谢谢你,塞巴斯蒂安。这绝对是我需要研究的东西,以便改进我为工作制作的脚本。为此干杯