我正在使用wget下载XML文件,但有时文件在第一行中有文本需要删除。
目前第一行有“131”,最后一行有“0”。
如果包含此信息,我需要一种删除这些行的方法。我不能做一个perl查找和替换,如果它不在那里,但正确的第一行包含“131”。
这有意义吗?
有什么想法吗?
由于
示例,有时是这样的:
131
<element>
<example>content</example>
<example>content</example>
<example>content</example>
<example>content</example>
</element>
0
有时候这样(正确)
<element>
<example>content</example>
<example>content</example>
<example>content</example>
<example>content</example>
</element>
答案 0 :(得分:1)
我认为这可能会让你到达目的地。
假设你刚刚为sample.xml做了一个wget,那么:
perl -pi -e '$/ = undef; s{(?: \A [^<]* | [^>]* \z )}{}xmsg;' sample.xml
剥离任何非&lt;从文件的开头和任何不是&gt;从文件的末尾开始。
答案 1 :(得分:1)
这是sed
的工作!你不会更快或更简单:
如果你确定这两个值,你可以简单地说:
sed -e '1{/^131$/d};${/^0$/d}' -i mybrokenfile
但是使用以下命令,sed
同时删除任何包含数字的第一行和/或最后一行:
sed -e '1{/^[0-9]\+$/d};${/^[0-9]\+$/d}'
这可以通过文件作为参数和备份文件自动生成来运行:
sed -e '1{/^[0-9]\+$/d};${/^[0-9]\+$/d}' -i.bak files*
说明:
1
和$
地址:第一行为1
,最后一行为$
。/^[0-9]\+$/
表示*行以0
和9
之间的一个或多个字符开头,并在紧接着之后结束。d
。这可以写成:
sed -e '1{
/^[0-9]\+$/d
}
${
/^[0-9]\+$/d
}' -i.bak files*
。
修改强>:
因为我讨厌写不止一次......大概是什么;
有一种方法可以做一些棘手的事情,但只能在第一行和最后一行。
首先,同样的样本可以写成:
sed -e '1ba;$ba;bb;:a;/^[0-9]\+$/d;:b;' -i.bak files*
因此 1 字节更短!但尤其是操作只写一次:
说明:
:a
和:b
是分支(跳转)到ba
和bb
分别是:a
和:b
的分支机构。1
和$
是前面描述的地址/.../d
也是先前描述的,意思是删除与正则表达式相匹配的行 可写:
sed -e '
1ba;
$ba;
bb;
:a;
/^[0-9]\+$/d;
:b;
' -i.bak files*
使用s/../../
代替d
的应用示例:
仅在第1行或最后一行出现时修改版本信息:
sed -e '1ba;$ba;bb;:a;s/\(Id: .*,v\).*\(Exp\)/\1'"$(
date +" $VER %F %T $USER ")"'\2/;b;' -i files*
答案 2 :(得分:0)
根据评论,您希望使用wget --save-headers
并使用正确的HTTP响应解析器。这其实很简单:
use HTTP::Response qw( );
my $response = HTTP::Response->parse($raw_response);
my $body = $response->decoded_content( charset => 'none' );
鉴于响应包括$raw_response
标题,上述代码将返回$body
中传输的XML(或其他)文档。
原始回复:
这是一个HTTP分块响应。
if ($file =~ /^[0-9]+\r?\n/) {
my $chunked = substr($file, 0, length($file), '');
for (;;) {
$chunked =~ s/^([0-9]+)\r?\n//
or die;
my $chunk_len = $1
or last;
length($file) >= $chunk_len
or die;
$file .= substr($chunked, 0, $chunk_len, '');
}
}