如何区分wget --save-headers输出的请求头与正文?脚本问题排查
如何区分wget带--save-headers输出中的HTTP头与正文?
当执行wget www.google.com --save-headers --output-document - --quiet命令时,HTTP响应头和正文的分界遵循HTTP协议规范:一个完全空的行(即连续两个换行符,格式可能是\r\n\r\n或\n\n),这是区分两部分的核心标志。
你的脚本问题分析
你最初的脚本逻辑本身没问题,但在执行echo $r时没有给变量$r加双引号,导致bash展开变量时会把所有换行、连续空白压缩成单个空格,原本的空行完全消失,awk无法识别分界点,最终导致body变量为空。
修正后的可行方案
给变量加上双引号后,bash会保留变量中的原始换行和空白结构,此时awk就能正确识别空行分界:
r=$(wget www.google.com --save-headers --output-document - --quiet) status=$(echo "$r" | grep HTTP | awk '{ print $2 }') body=$(echo "$r" | awk '{ if( $0 ~ /^[\s]*$/ ) { b=1 }; if( b ) { print $0 } }')
更高效的优化方案
不需要先把结果存入变量,直接通过管道串联处理,避免变量展开问题的同时减少内存占用:
wget www.google.com --save-headers --output-document - --quiet | tee >(grep HTTP | awk '{print $2}' > status.txt) | awk '{ if( $0 ~ /^[\s]*$/ ) { b=1 }; if( b ) { print $0 } }' > body.html
这个命令通过tee将输出同时分流到两个管道:
- 一个管道提取状态码并写入
status.txt文件 - 另一个管道提取正文并写入
body.html文件
原理补充
HTTP协议明确规定,响应头结束后必须紧跟一个空行,之后的内容才是正文。awk脚本通过标记b实现控制:当匹配到空行时将b设为1,之后所有行都输出,以此精准提取正文部分。
内容的提问来源于stack exchange,提问作者Richard Barraclough
相关产品推荐
相关产品推荐

