sed - 不能让sed表达工作

时间:2014-09-09 20:37:10

标签: bash sed cygwin

解析curl的详细输出(例如):

>
* STATE: DO => DO_DONE handle 0x60002e090; line 1281 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x60002e090; line 1407 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x60002e090; line 1420 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Date: Mon, 08 Sep 2014 16:34:30 GMT
* Server Apache/2.2.3 (Win32) mod_ssl/2.2.3 OpenSSL/0.9.8c mod_jk/1.2.19 PHP/5.2.7-dev is not blacklisted
< Server: Apache/2.2.3 (Win32) mod_ssl/2.2.3 OpenSSL/0.9.8c mod_jk/1.2.19 PHP/5.2.7-dev
< Set-Cookie: JSESSIONID=B256C7DA85AF756B86252810830C9284; Path=/hcs; Secure
< Transfer-Encoding: chunked
< Content-Type: text/html;charset=ISO-8859-1
<
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0{ [data not shown]
* STATE: PERFORM => DONE handle 0x60002e090; line 1590 (connection #0)

我需要使用以下格式生成带有HTTP状态代码和标头的列表:

:STATUS: 200
Date: Mon, 08 Sep 2014 16:34:30 GMT
Server: Apache/2.2.3 (Win32) mod_ssl/2.2.3 OpenSSL/0.9.8c mod_jk/1.2.19 PHP/5.2.7-dev
Set-Cookie: JSESSIONID=B256C7DA85AF756B86252810830C9284; Path=/hcs; Secure
Transfer-Encoding: chunked
Content-Type: text/html;charset=ISO-8859-1

我创建的sed行是:

cat $result | sed -rn '/^< /!d; s/^<\s+//; /^$/d; /:/!{s/\S+\s+//; s/\s.*//; s/^/:STATUS: /; h}; /:/H; ${x;p}'

但我得到的只是一个空洞的结果......任何想法?

jose@DESKTOP-72
$ cat io.txt | sed -rn '/^< /!d; /^$/d; /:/!{s/\S+\s+//; s/\s.*//; s/^/:STATUS: /; h}; /:/H; ${x;p}'

jose@DESKTOP-72

我在Cygwin 1.7.30(0.272 / 5/3)下通过MS Windows 8运行此脚本。

提前致谢, 何

2 个答案:

答案 0 :(得分:1)

我认为awk更直接。

试试这行:

awk '$1=="<" && NF>2 && sub(/^< /,""){if(!/:/)$0=":STATUS: "$2;print}' io.txt

答案 1 :(得分:0)

不是sed专家,没有时间更多地解决这个问题,但sed -r '/^< /!d; s/^<\s+//; /^$/d; /:/!{s/\S+\s+//; s/\s.*//; s/^/:STATUS: /}'似乎做了你想做的事情(至少对于那个例子输入)。

实际上,在输入时(以及我正在运行的其他一些测试),我想我理解这个问题。您的$地址永远不会匹配,因为您删除该地址之前有可能触发的最后一行。将其移动到sed脚本的开头,它会打印出数据。 (它将第一行加倍,但它会全部打印出来。)

curl -s -D- -o/dev/null的输出是否符合您的需求?

如果不是curl -s -D- -o/dev/null "$SITE" | awk 'NR==1{print ":STATUS:",$2}7看起来像你要求的那样。