1

在 shell 中执行它会给我带来切实的结果:

wget -O c1 --no-cache "http://some.website" | sed "1,259d" c1 | sed "4,2002d"

在 Python 中执行此操作对我一无所获:

subprocess.call(shlex.split("wget -O c1 --no-cache \"http://some.website/tofile\""))
c1 = open("c1",'w')
first = subprocess.Popen(shlex.split("sed \"1,259d\" c1"), stdout=subprocess.PIPE)

subprocess.Popen(shlex.split("sed \"4,2002d\""), stdin=first.stdout, stdout=c1)
c1.close()

这样做也没有结果:

c1.write(subprocess.Popen(shlex.split("sed \"4,2002d\""), stdin=first.stdout, stdout=subprocess.PIPE).communicate()[0])

“让我一无所获”是指文件中的空白输出。有没有人看到这里有什么不寻常的地方?

4

4 回答 4

3

我总是使用铅锤来运行外部命令。它提供了一个非常直观的界面,当然,它会为我提供转义。

看起来像:

from plumbum.cmd import wget, sed
cmd1 = wget['-O', 'c1']['--no-cache']["http://some.website"]
cmd2 = sed["1,259d"]['c1'] | sed["4,2002d"]
print cmd1
cmd1()  # run it
print cmd2
cmd2()  # run it
于 2013-03-14T06:46:14.827 回答
2

该语句c1 = open("c1",'w')打开文件c1以进行写入并截断任何现有数据,因此 wget 写入文件的所有内容都会在您调用 sed 之前被删除。

反正我觉得shlex.split一般都挺尴尬的。我更喜欢手动构建 args 列表:

from subprocess import Popen, PIPE

p0 = Popen(['wget', '-O', '-', 'http://www.google.com'], stdout=PIPE)
p1 = Popen(['sed', '2,8d'], stdin=p0.stdout, stdout=PIPE) 
with open('c1', 'w') as c1:
    p2 = Popen(['sed', '2,7d'], stdin=p1.stdout, stdout=c1)
    p2.wait()

但是,没有明显的理由让 Python 程序员不得不调用 sed。Python 有字符串方法和正则表达式。此外,您可以使用 wget 而不是urllib2.urlopen.

于 2013-03-14T08:47:43.630 回答
1

为什么不只在管道中完成所有操作并将输出发送到文件?

wget -O - "http://www.google.com" | sed "1,259d" | sed "4,2002d" > c1

或者,如果您不想将其发送到文件,而是希望将其放在标准输出上:

wget -O - "http://www.google.com" | sed "1,259d" | sed "4,2002d"

如果你想在 Python 中做到这一点:

pipe = subprocess.Popen(shlex.split("wget -O - \"http://www.google.com\" | sed \"1,259d\" | sed \"4,2002d\""), stdout=subprocess.PIPE)
result = pipe.communicate()[0]
于 2013-03-14T06:18:51.850 回答
0

为了让那些或多或少遇到相同类型问题的人的生活更轻松,我决定发布最终修订的代码,其中考虑了c1对数据的评论和覆盖。特别令人感兴趣的是它的使用communicate()有助于完全消除僵尸进程的任何表现,这非常令人恼火。subprocess.call此外,我发现在不需要管道的部分使用它很有用。最终没有wait()必要。最终,远离sed并且wget是一个好主意,尤其是使用 Python 的内置工具和urllib2.

p0 = subprocess.call(shlex.split("wget -Oc1 --no-cache \"http://Some.website/tofile\""))
p1 = subprocess.Popen(shlex.split("sed \"1,261d\" c1"), stdout=subprocess.PIPE)

with open("cc1", 'w') as cc1:
    p2 = subprocess.Popen(shlex.split("sed \"3,2002d\""), stdin=p1.stdout, stdout=cc1)
    p2.communicate()
    p1.communicate()
    p3 = subprocess.call(shlex.split("mv cc1 c1"))
于 2013-03-15T06:42:13.477 回答