我在Red Hat Linux中运行以下命令:
perl -ne '
print "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
while(/(<PRINTKIT FORM_ID=\"PP_WELCOMEKIT\">.*?<\/PRINTKIT>)/g){
print "<sf><XDF>$1</XDF></sf>"
};
' $1 > $2.$TS2.postscrub
$2
是文件名,$TS2
只是一个日期。
目前它打印出100行
<?xml version=\"1.0\" encoding=\"utf-8\"?>
当我真的不想要打印任何内容时。
有人可以更改上面的代码来执行它正在执行的所有操作,但不再打印<?xml version=\"1.0\" encoding=\"utf-8\"?>
了吗?我已经尝试过删除带有该行的print语句,如下所示:
perl -ne '
while(/(<PRINTKIT FORM_ID=\"PP_WELCOMEKIT\">.*?<\/PRINTKIT>)/g){
print "<sf><XDF>$1</XDF></sf>"
};
' $1 > $2.$TS2.postscrub
这样做会使它输出一个0字节的文件,所以我知道它不起作用。
答案 0 :(得分:7)
真的 - 请不要使用正则表达式来操纵XML
。它是非常令人讨厌的,正如你所发现的那样 - 容易被莫名其妙地打破。
尝试这样的事情(我猜测了你的样本数据)。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
sub replace_printkit {
my ( $twig, $pk ) = @_;
my $sf = $twig->root->insert_new_elt('sf');
$sf->insert_new_elt( 'XDF', $pk->trimmed_text );
$pk->delete;
}
my $twig = XML::Twig->new(
'pretty_print' => 'indented',
'twig_handlers' => { 'PRINTKIT' => \&replace_printkit }
);
$twig->parse( \*DATA );
$twig->set_xml_version('1.0');
$twig->set_encoding('utf-8');
$twig->print;
__DATA__
<xml>
<PRINTKIT FORM_ID="PP_WELCOMEKIT">some_stuff_here</PRINTKIT>
</xml>
打印:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<sf>
<XDF>some_stuff_here</XDF>
</sf>
</xml>
您可能需要稍微修改输入数据。
编辑:
当您使用$ twig-&gt; print时,我可以将其放入文件中吗?如果是这样,命令是什么?
open ( my $output_fh, '>', "new_file.xml" ) or die $!;
print {$output_fh} $twig -> sprint;
close ( $output_fh );
答案 1 :(得分:4)
除了使用正则表达式XML的可取性之外,这个问题的简单答案是:&#34;如何阻止这个Perl命令一遍又一遍地打印XML声明?&#34;是将XML声明包装在BEGIN
块中。
BEGIN { print "<?xml version=\"1.0\" encoding=\"utf-8\"?>" }
perlrun描述了-n
切换效果:
导致Perl在程序周围采用以下循环,这使得它迭代文件名参数,有点像sed -n或awk
LINE:
while (<>) {
... # your program goes here
}
因此,无论你在-n
程序的主体中放置什么,都会为每行输入运行,从而重复打印XML标记。如果用BEGIN包装它,它就不会那么做。
但是,-n
行为所以为Perl建立了,并且重复XML标记对于XML来说是非标准的,所以它很适合任何人#39解决方案的想法。我几乎怀疑那些不知道它在做什么的人,删除了BEGIN
块,只是因为它是一个明显的候选者。
答案 2 :(得分:4)
perl -ne'
BEGIN { print "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; }
while(/(<PRINTKIT FORM_ID=\"PP_WELCOMEKIT\">.*?<\/PRINTKIT>)/g){
print "<sf><XDF>$1</XDF></sf>"
}
' $1 > $2.$TS2.postscrub
或
perl -ne'
print "<?xml version=\"1.0\" encoding=\"utf-8\"?>" if $. == 1;
while(/(<PRINTKIT FORM_ID=\"PP_WELCOMEKIT\">.*?<\/PRINTKIT>)/g){
print "<sf><XDF>$1</XDF></sf>"
}
' $1 > $2.$TS2.postscrub
或
perl -e'
print "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
while (<>) {
while(/(<PRINTKIT FORM_ID=\"PP_WELCOMEKIT\">.*?<\/PRINTKIT>)/g){
print "<sf><XDF>$1</XDF></sf>"
}
}
' $1 > $2.$TS2.postscrub
答案 3 :(得分:0)
您必须保留参数-n。它为您的代码添加了一个while循环。你只需要一个有效的while循环,将其更改为读取所有行(while (<>)
),你可以将你的条件放在print语句之后,如下所示:
perl -e '
print "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
while(<>) {
print "<sf><XDF>$1</XDF></sf>" if(/(<PRINTKIT FORM_ID=\"PP_WELCOMEKIT\">.*?<\/PRINTKIT>)/g);
};' $1 > $2.$TS2.postscrub