我有一个如下的文本文件。
1001=<?xml ns=dkfj><home><taga>dkjf</taga></home>1002=<?xml ns=dkfj><home1><taga>dkjf</taga></home1>
我需要如下结果。
<?xml ns=dkfj><home><taga>dkjf</taga></home>
<?xml ns=dkfj><home1><taga>dkjf</taga></home1>
我尝试过sed,开始和结束模式,但它不起作用,因为两者都在同一行。
我该怎么做?
答案1
原来的问题将由
cat test.xml | tr "<" "\n" | sed -n '/taga>./p' | sed 's/taga>//'
第二个解决,当前的问题将由
cat test.xml | sed 's/[0-9][0-9][0-9][0-9]=/\n/g'
它会查找四个数字后跟 = 符号的出现,因此如果您在实际字符串的其他位置可能有这些类型的字符,它将无法工作,但现在看起来不是这样
答案2
查看您的代码片段,您似乎已经获得了由“number=”分隔的 XML。所以用 split 来提取:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
local $/;
my @xml_chunks = split ( /\d+\=/, <> );
print Dumper \@xml_chunks;
当然,您可能应该注意 - 您的 XML ...不是。该声明无效。不过,我假设这是一个换位错误。但它应该是这样的:
<?xml version="1.0" encoding="utf-8"?>
因此,对于您的示例数据,这将合理地近似修复 XML(当然假设它无效)。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
use Data::Dumper;
local $/;
my @xml_chunks = split( /\d+\=/, <DATA> );
print Dumper \@xml_chunks;
foreach my $chunk ( grep {/xml/} @xml_chunks ) {
$chunk =~ s/^<[^>]+>//;
my $twig = XML::Twig->new( pretty_print => 'indented_a' );
$twig->parse($chunk);
$twig->set_encoding('utf-8');
$twig->set_xml_version('1.0');
$twig->root->set_att( 'xmlns', 'http://www.some_ns.com' );
$twig->print;
}
答案3
我认为 sed 会起作用,但我会做一个 perl 解决方案:
perl -ane 'while (/(<\?xml.*?>)($|\d+=)/g) { push @w,$1; }' \
-e 'print join("\n",@w)."\n";@w=();'
Perl 中的正则表达式操作/g
说“启动下一个正则表达式从此处开始匹配”。如果没有匹配,则正则表达式返回 0(假),结束循环while
,允许密码子打印您的输出。同时,匹配项会累积在数组中@w
,您必须清除该数组在正则表达式中,我假设您的搜索边界本质上是数字和等号。