我在目录中有几个名为TC_Circle1
,TC_Circle2
,`TC_Point1等的XML文件,我想使用脚本来更新每个文件中的开始和停止日期。开始和停止日期在内部,每个文件中都有标签。
我有一个脚本在我们使用Sun机器时起作用,但它不适用于新的HP Linux机器。它不显示任何错误,也不会更改日期。我需要帮助它在Linux中工作。脚本:
#!/usr/local/bin/perl
$numArgs = @ARGV;
if ($numArgs != 2)
{
print "Usage: replace_default_date.pl DEFAULT_START_DATE DEFAULT_STOP_DATE\n";
}
@filenames = `ls TC*`;
chomp(@filenames);
foreach $file (@filenames)
{
open(REGFILE, "$file") || die "Cannot open |$file|";
@lines = <REGFILE>;
close(REGFILE);
open(WRITEFILE), ">$file") || die "Cannot open |$file|";
foreach $line (@lines)
{
if ($line =~ /DEFAULT_START_DATE/)
{
$newline = " " . $ARGV[0];
print WRITEFILE "$newline\n";
}
elsif ($line =~ /DEFAULT_STOP_DATE/)
{
$newline = " " . $ARGV[1];
print WRITEFILE "$newline\n";
}
else
{
print WRITEFILE "$line\n";
}
}
close (WRITEFILE);
}
以下是要修改的文件在开头看的方式:
<RequestSomething xmlns="http://something.com/accessservice">
<period xmlns="">
<start>2013-03-06T00:00:00</start>
<stop>2013-03-07T00:00:00</stop>
</period>
... The rest of the xml file...
</RequestSomething>
提前致谢, 晶体
答案 0 :(得分:1)
您的脚本存在一些问题。
1)由于额外的右括号,存在编译错误:
打开(WRITEFILE),“&gt; $ file”)||死“无法打开| $ file |”;
应该写为
打开(WRITEFILE,“&gt; $ file”)||死“无法打开| $ file |”;
2)你应该在
中使用反引号而不是单引号@filenames = 'ls TC*';
否则@filenames
将只包含字符串'ls TC *'而不是实际的文件名列表:
@filenames = `ls TC*`;
3)你确定perl解释器的路径是/usr/local/bin/perl
吗?
(从命令行尝试which perl
以检查路径)。如果不是那么第一行应该改变。
4)该脚本永远不会对您向我们展示的XML数据起作用,因为它旨在替换包含字符串 DEFAULT_START_DATE 和 DEFAULT_STOP_DATE 的行(日期提供为脚本的参数)。这些字符串不会出现在您向我们展示的数据中。
但是,如果XML文件是这样的话,该脚本将起作用:
<RequestSomething xmlns="http://something.com/accessservice">
<period xmlns="">
<start>
DEFAULT_START_DATE
</start>
<stop>
DEFAULT_STOP_DATE
</stop>
</period>
... The rest of the xml file...
</RequestSomething>
我希望这可以帮助你让它工作,但无论如何我建议你重写脚本,因为它使用了一种非常不可靠和危险的方式来更改XML文件。
答案 1 :(得分:0)
由于您想要做的事情相对简单,因此您并不需要将其视为.xml。我会像你一样对待它,以免混淆。对于你的方式,似乎Tie :: File是一个很好的选择。例如:
的test.xml:
<RequestSomething xmlns="http://something.com/accessservice">
<period xmlns="">
<start>2013-03-06T00:00:00</start>
<stop>2013-03-07T00:00:00</stop>
</period>
... The rest of the xml file...
</RequestSomething>
代码:
use Tie::File;
use strict;
use warnings;
my @ra=();
tie @ra, 'Tie::File', "test.xml" or die;
my $length=scalar(@ra);
for (my $i=0; $i < $length; $i++)
{
if ($ra[$i] =~ /(\s*)<start>.*<\/start>/)
{
$ra[$i]="$1<start>$ARGV[0]<\/start>";
}
elsif ($ra[$i] =~ /(\s*)<stop>.*<\/stop>/)
{
$ra[$i]="$1<stop>$ARGV[1]<\/stop>";
}
}
使用Tie :: File,您可以进入您的文件,并使用数组来访问/修改其内容。
(\s*)<stop>.*<\/stop>
基本上执行以下操作:(\ s *)在$ 1之前提取所有空格。 <stop>.*<\/stop>
在它们之间查找包含任何非换行符的停止标记。一旦我们知道我们在正确的行中,我们只需通过修改数组来改变该行,正如我所说的直接更改文件。我们把1美元放在那里以保留缩进。
这里是我执行perl test.pl 1am 2pm时的新test.xml:
<RequestSomething xmlns="http://something.com/accessservice">
<period xmlns="">
<start>1am</start>
<stop>2pm</stop>
</period>
... The rest of the xml file...
</RequestSomething>
您可以添加选项以浏览所有必需的文件,只需确保在每个文件之后重置数组,即@ ra =();祝好运。希望这有帮助!
编辑:看看关于解开阵列的评论,你也应该这样做。答案 2 :(得分:0)
为什么不使用XML解析器?你不能在那台机器上安装CPAN吗?
如果文件不大,您可以使用XML::Simple
,否则使用XML::Twig
- 如果您不习惯回调处理程序可能会很棘手。
我用XML::XPath
向您展示了一个简单的方法。
use XML::XPath;
use DateTime;
my $xp = XML::XPath->new(filename => 'input.xml');
$xp->setNodeText('/RequestSomething/period/start', DateTime->now->strftime("%FT%T"));
$xp->setNodeText('/RequestSomething/period/stop', DateTime->now->add(days=>1)->strftime("%FT%T"));
open my $fh, '>', 'output.xml' or die "$!";
print $fh $xp->getNodeAsXML();
close $fh;
我使用DateTime
来设置当前日期,但您当然可以不使用它。