0

我正在使用 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>
4

3 回答 3

1

我认为这可能会让你到达你想去的地方。

假设您刚刚为 sample.xml 做了一个 wget,那么:

perl -pi -e '$/ = undef; s{(?: \A [^<]* | [^>]* \z )}{}xmsg;' sample.xml

这会从文件的开头删除非 < 的任何内容,以及从文件末尾删除任何非 > 的内容。

于 2012-11-25T18:06:58.740 回答
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是分支(跳转)到的标签
  • babb分别是 和 的分支:a指令:b
  • 1并且$是如前所述的地址
  • /.../d前面也描述过,意思是删除匹配正则表达式的行

并且可以写成:

sed -e '
    1ba;
    $ba;
    bb;
   :a;
    /^[0-9]\+$/d;
   :b;
  ' -i.bak files*

应用程序示例,s/../../而不是仅使用d:仅在第一行或最后一行出现时修改版本信息:

 sed -e '1ba;$ba;bb;:a;s/\(Id: .*,v\).*\(Exp\)/\1'"$(
             date +" $VER %F %T $USER ")"'\2/;b;' -i files*
于 2012-11-25T18:19:46.083 回答
0

根据评论,您想使用wget --save-headers和使用适当的 HTTP 响应解析器。这实际上很简单:

use HTTP::Response qw( );
my $response = HTTP::Response->parse($raw_response);
my $body = $response->decoded_content( charset => 'none' );  

给定包含标题的响应 via $raw_response,上面的代码将返回传输的 XML(或其他)文档$body


原始回复:

这是一个 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, '');
   }
}
于 2012-11-24T19:35:33.003 回答