尝试在python中将bash语句转换为子进程
我正在尝试用python将bash命令转换为子进程。bash命令是: cat LogFile.msg.log | grep ABCD | awk'{print$14,$10,$5,$7}'| sort-t'-k4-n-r | head-10>output.csv 到目前为止,我为子流程提供了以下内容:尝试在python中将bash语句转换为子进程,python,subprocess,output,pipeline,export-to-csv,Python,Subprocess,Output,Pipeline,Export To Csv,我正在尝试用python将bash命令转换为子进程。bash命令是: cat LogFile.msg.log | grep ABCD | awk'{print$14,$10,$5,$7}'| sort-t'-k4-n-r | head-10>output.csv 到目前为止,我为子流程提供了以下内容: cat = subprocess.Popen(['cat', 'LogFile.msg.log'], stdout=subprocess.PIPE,
cat = subprocess.Popen(['cat', 'LogFile.msg.log'],
stdout=subprocess.PIPE,
)
grep = subprocess.Popen(['grep', 'ABCD'],
stdin=cat.stdout,
stdout=subprocess.PIPE,
)
awk = subprocess.Popen(['awk', '{print $14,$10,$5,$7}'],
stdin=grep.stdout,
stdout=subprocess.PIPE,
)
sort = subprocess.Popen(['sort', '-t','' '', '-k4', '-n', '-r'],
stdin=awk.stdout,
stdout=subprocess.PIPE,
)
head = subprocess.Popen(['head', '-10'],
stdin=sort.stdout,
stdout=subprocess.PIPE,
)
out = subprocess.Popen(['>', 'output.csv'],
stdin=head.stdout,
stdout=subprocess.PIPE,
)
end_of_pipe = out.stdout
现在我收到以下错误:
Sort: empty tab
Traceback (most recent call last):
File "./latency2", line 39, in <module>
stdout=subprocess.PIPE,
File "/usr/lib64/python2.6/subprocess.py", line 639, in __init__
errread, errwrite)
File "/usr/lib64/python2.6/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
排序:空选项卡
回溯(最近一次呼叫最后一次):
文件“/latency2”,第39行,在
stdout=子流程.PIPE,
文件“/usr/lib64/python2.6/subprocess.py”,第639行,在__
错误读取,错误写入)
文件“/usr/lib64/python2.6/subprocess.py”,第1228行,在执行子进程中
引发子对象异常
OSError:[Errno 2]没有这样的文件或目录
我肯定我遗漏了什么,但不确定遗漏了什么。您有两个问题。首先,您没有正确地将参数转换为
sort
。运行此sort
命令时:
sort -t' ' -k4 -n -r
shell将标记-t
和'
粘贴到单个参数“-t”
(短划线、t形三通、空格)中。因此,正确的子流程参数应该是:
sort = subprocess.Popen(['sort', '-t ', '-k4', '-n', '-r'],
stdin=awk.stdout,
stdout=subprocess.PIPE,
)
第二个问题是最终重定向到带有>output.csv
标记的文件。当shell看到这一点时,它不会运行名为
的命令;相反,它打开文件output.csv
进行写入,并将其设置为最后一个命令的标准输出句柄。因此,您不应该尝试将名为
的命令作为子进程运行;相反,您需要通过打开一个文件来模拟shell:
head = subprocess.Popen(['head', '-10'],
stdin=sort.stdout,
stdout=open('output.csv', 'w'), # Not a pipe here
)
你可以重写:
cat LogFile.msg.log | grep ABCD | awk '{print $14,$10,$5,$7}' |
sort -t' ' -k4 -n -r | head -10 > output.csv
在纯Python中:
from heapq import nlargest
from operator import itemgetter
select_items = itemgetter(13, 9, 4, 6) # note: zero-based indices
with open('LogFile.msg.log') as file, open('output.csv', 'w') as outfile:
rows = (select_items(line.split()) for line in file if 'ABCD' in line)
top10_rows = nlargest(10, rows, key=lambda row: int(row[3]))
print("\n".join(map(" ".join, top10_rows)))
你确定你的工作目录是正确的吗?那很好用。我知道我对.csv的输出被提升了。谢谢我还有一个问题。在我的第一行中,我试图搜索一个包含今天当前日期的文件。bash语句使用日志文件\u'date+%Y%m%d'.msg.log(日志文件\u 20120410.msg.log)工作。但这在子流程中不起作用。我得到“没有这样的文件或目录”。你知道为什么这不能在子流程中正确翻译吗?