我想从python shell运行bash命令。 我的bash是:
grep -Po "(?<=<cite>).*?(?=</cite>)" /tmp/file1.txt | awk -F/ '{print $1}' | awk '!x[$0]++' > /tmp/file2.txt
我尝试的是:
#!/usr/bin/python
import commands
commands.getoutput('grep ' + '-Po ' + '\"\(?<=<dev>\).*?\(?=</dev>\)\" ' + '/tmp/file.txt ' + '| ' + 'awk \'!x[$0]++\' ' + '> ' + '/tmp/file2.txt')
但我没有任何结果。
谢谢
答案 0 :(得分:3)
在python中运行系统命令的推荐方法是使用模块subprocess。
import subprocess
a=['grep' ,'-Po', '"(?<=<dev>).*?(?=</dev>)"','/tmp/file.txt']
b=['awk', '-F/', '"{print $1}"']
c=["awk", '"!x[$0]++"']
p1 = subprocess.Popen(a,stdout=subprocess.PIPE)
p2 = subprocess.Popen(b,stdin=p1.stdout,stdout=subprocess.PIPE)
p3 = subprocess.Popen(c,stdin=p2.stdout,stdout=subprocess.PIPE)
p1.stdout.close()
p2.stdout.close()
out,err=p3.communicate()
print out
在每个子进程之间创建管道的目的是出于安全和调试的原因。此外,它使代码更清晰,哪个进程获取输入并将输出发送到。
答案 1 :(得分:2)
如果您想避免拆分参数并担心管道问题,可以使用shell=True
选项:
cmd = "grep -Po \"(?<=<dev>).*?(?=</dev>)\" /tmp/file.txt | awk -F/ '{print $1}' | awk '!x[$0]++' > file2.txt"
out = subprocess.check_output(cmd, shell=True)
这将运行一个子shell,它将理解你的所有指令,包括“|”用于管道,“&gt;”用于重定向。如果你不这样做,通常由shell解析的这些符号将被传递给grep程序。
否则,您必须自己创建管道。例如(下面未经测试的代码):
grep_p = subprocess.Popen(["grep", "-Po", "(?<=<dev>).*?(?=</dev>)", "/tmp/file.txt"], stdout=subprocess.PIPE)
awk_p = subprocess.Popen(["awk", "-F/", "'{print $1}'"], stdin = grep_p.stdout)
file2_fh = open("file2.txt", "w")
awk_p_2 = subprocess.Popen(["awk", "!x[$0]++", stdout = file2_fh, stdin = awk_p.stdout)
awk_p_2.communicate()
但是,如果你这样做,你就错过了python的观点。您应该查看re模块:re.match
,re.sub
,re.search
,尽管我不太熟悉awk来翻译您的命令。
答案 2 :(得分:1)
你必须使用
import os
os.system(command)
答案 3 :(得分:1)
让我们编写一个简单的函数来轻松处理这些混乱的管道:
def subprocess_pipes (pipes, last_pipe_out = None):
import subprocess
from subprocess import PIPE
last_p = None
for cmd in pipes:
out_pipe = PIPE if not (cmd==pipes[-1] and last_pipe_out) else open(last_pipe_out, "w")
cmd = cmd if isinstance(cmd, list) else cmd.split(" ")
in_pipe = last_p.stdout if last_p else None
p = subprocess.Popen(cmd, stdout = out_pipe, stdin = in_pipe)
last_p = p
comm = last_p.communicate()
return comm
然后我们跑,
subprocess_pipes(("ps ax", "grep python"), last_pipe_out = "test.out.2")
结果是&#34; test.out.2&#34;带有管道内容的文件&#34; ps ax&#34;进入&#34; grep python&#34;。
在你的情况下,
a = ["grep", "-Po", "(?<=<cite>).*?(?=</cite>)", "/tmp/file1.txt"]
b = ["awk", "-F/", "{print $1}"]
c = ["awk", "!x[$0]++"]
subprocess_pipes((a, b, c), last_pipe_out = "/tmp/file2.txt")
答案 4 :(得分:0)
commands
模块现已过时。
如果您实际上不需要输出命令,可以使用
import os
exit_status = os.system("your-command")
否则你可以使用
import suproccess
out, err = subprocess.Popen("your | commands", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell = True).communicate()
注意:对于您的命令,您将stdout发送到file2.txt
,因此我不希望在out
中看到任何内容,但您仍然会在stderr上看到有关err
的错误消息
答案 5 :(得分:-1)
我认为你要找的是:
ubprocess.check_output(same as popen arguments, **kwargs)
,以与使用popen
命令相同的方式使用它,它应该显示正在调用的程序的输出。
有关详情,请点击此链接:http://freefilesdl.com/how-to-call-a-shell-command-from-python/