如何在Linux中从HTTP MIME编码的消息中提取文件数据?
我有一个程序,接受HTTP post文件并将所有post结果写入一个文件,我想写一个脚本来删除HTTP头,只留下二进制文件数据,怎么办 文件内容如下(我需要如何在Linux中从HTTP MIME编码的消息中提取文件数据?,linux,bash,sed,awk,Linux,Bash,Sed,Awk,我有一个程序,接受HTTP post文件并将所有post结果写入一个文件,我想写一个脚本来删除HTTP头,只留下二进制文件数据,怎么办 文件内容如下(我需要内容类型:application/octet stream和------KM7cH2GI3cH2Ef1Ij5gL6GI3Ij5GI3之间的数据: POST /?user_name=vvvvvvvv&size=837&file_name=logo.gif& HTTP/1.1^M Accept: text/*^M Cont
内容类型:application/octet stream
和------KM7cH2GI3cH2Ef1Ij5gL6GI3Ij5GI3
之间的数据:
POST /?user_name=vvvvvvvv&size=837&file_name=logo.gif& HTTP/1.1^M
Accept: text/*^M
Content-Type: multipart/form-data; boundary=----------KM7cH2GI3cH2Ef1Ij5gL6GI3Ij5GI3^M
User-Agent: Shockwave Flash^M
Host: 192.168.0.198:9998^M
Content-Length: 1251^M
Connection: Keep-Alive^M
Cache-Control: no-cache^M
Cookie: cb_fullname=ddddddd; cb_user_name=cdc^M
^M
------------KM7cH2GI3cH2Ef1Ij5gL6GI3Ij5GI3^M
Content-Disposition: form-data; name="Filename"^M
^M
logo.gif^M
------------KM7cH2GI3cH2Ef1Ij5gL6GI3Ij5GI3^M
Content-Disposition: form-data; name="Filedata"; filename="logo.gif"^M
Content-Type: application/octet-stream^M
^M
GIF89an^@I^^M
------------KM7cH2GI3cH2Ef1Ij5gL6GI3Ij5GI3^M
Content-Disposition: form-data; name="Upload"^M
^M
Submit Query^M
------------KM7cH2GI3cH2Ef1Ij5gL6GI3Ij5GI3-
如果您使用Python,将允许您解析一个多部分MIME文档。这可能是一个疯狂的想法,但我会尝试使用procmail剥离标题。这可能包含一些打字错误或其他内容,但无论如何请容忍。首先确定边界(
输入
是包含数据管道的文件,如果需要):
然后过滤Filedata
部分:
fd='Content-Disposition: form-data; name="Filedata"'
sed -n "/$fd/,/$boundary/p"
最后一部分是过滤一些额外的行-前面的标题行,包括空行和边界本身,因此将最后一行从previous更改为:
sed -n "/$fd/,/$boundary/p" | sed '1,/^$/d' | sed '$d'
过滤sed-n/$fd/,/$boundary/p”
头和边界(包括)之间的行Filedata
正在删除第一行之前的所有内容(因此会删除标题),并且sed'1,/^$/d'
删除最后一行(边界)sed'$d'
sed "1,/$fd/d;/^$/d;/$boundary/,$d"
既然您已经来到这里,请从头开始,按照Ignacio的建议去做。原因-这可能无法(可靠地)实现,因为GIF是二进制数据
啊,这是一个很好的练习!无论如何,对于sed
的爱好者来说,这是一个非常好的页面:
出色的信息。看看for Perl。它有一组丰富的类;我相信您可以在几行中组合一些内容。您希望在文件处理时这样做,还是在文件处理后这样做 几乎任何脚本语言都应该可以工作。我的AWK有点生疏,但是
awk '/^Content-Type: application\/octet-stream/,/^--------/'
这将打印应用程序/octet流
和-----------
行之间的所有内容。它还可能同时包括这两行,这意味着您必须执行更复杂的操作:
BEGIN {state = 0}
{
if ($0 ~ /^------------/) {
state = 0;
}
if (state == 1) {
print $0
}
if ($0 ~ /^Content-Type: application\/octet-stream/) {
state = 1;
}
}
application\/octet-stream
行位于print语句之后,因为您希望在看到application/octet-stream
后将state
设置为1
当然,作为Unix,您可以通过awk将程序的输出导入,然后保存文件。无需在结尾处调用
sed
三次:sed“1,/$fd/d;/$boundary/,$d”
@Dennis Sweet-只需要另一个(在Filedata头之后删除额外的头):sed“1,/$fd/d;//$/d;/$boundary/,$d”
。我将编辑以添加。
BEGIN {state = 0}
{
if ($0 ~ /^------------/) {
state = 0;
}
if (state == 1) {
print $0
}
if ($0 ~ /^Content-Type: application\/octet-stream/) {
state = 1;
}
}