当我从Linux提示符执行它时,以下shell脚本工作正常,但是当它被Unix服务(例如inetd等)调用时,它不会识别{{1}在Perl脚本中的变量。
$ACT_NUM
export ACT_NUM=$1
perl -pi -e '$v=$ENV{ACT_NUM};s/TRIGGER_VALUE" value="\d*"/TRIGGER_VALUE" value="$v"/>//' soa_triggering.xml
内容文件是
soa_triggering.xml
答案 0 :(得分:6)
我认为你的问题比$1
的扩展更为根本 - 我会冒险猜测正则表达式不匹配 - 因为:
$v=$ENV{ACT_NUM};s/TRIGGER_VALUE" value="\d*"/TRIGGER_VALUE" value="$v"/>//
实际上是语法损坏 - 您使用/
作为正则表达式分隔符,但是 还尝试将其包含在您的模式中。
因此,如果您实际运行此代码,则会得到:
Useless use of numeric gt (>) in void context
所以也许您需要考虑转义一些元字符:
这有效:
#!/usr/bin/env perl
use strict;
use warnings;
$ENV{ACT_NUM} = 1;
while ( <DATA> ) {
my $v=$ENV{ACT_NUM};
s/TRIGGER_VALUE\" value=\"\d*\"/TRIGGER_VALUE\" value=\"$v\"/;
print;
}
__DATA__
<ins:Parameter name="TRIGGER_VALUE" value="1"/>
但实际上 - 使用正则表达式弄乱XML
是inherently bad idea。
您还可能需要仔细检查实际上是否正在传播该环境。如果您print $v
(或$ENV{ACT_NAME}
)确实有效吗?
那么如何:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(
twig_handlers => {
'ins:Parameter[@name="TRIGGER_VALUE"]' =>
sub { $_->set_att( 'value', $ENV{ACT_NUM} ) }
}
);
$twig->parse(
do { local $/; <> }
)->print;
答案 1 :(得分:2)
正则表达式不足以表达解析XML。例如,您的相同值可以在三行中写出,参数顺序颠倒,如:
<ins:Parameter
value="1"
name="TRIGGER_VALUE"/>
......或许多其他差异(意外的空白,&amp; c)。试图涵盖角落案例 - 其中还包括CDATA中的区分内容和实际标签中的注释 - 是potentially sanity-impacting。
如果您正在编辑XML,请使用实际的XML解析器。一个不错的选择是XMLStarlet:
xmlstarlet ed -i \
-u '//*[@name="TRIGGER_VALUE"]/@value' \
-v "$ACT_NUM" \
soa_triggering.xml
如果您知道ins
命名空间指向的内容,您可以做得更好:
# Replace http://example.com/ins-namespace with actual value
# from xmlns:ins="..." earlier in your document
xmlstarlet ed -i -N "ins=http://example.com/ins-namespace" \
-u '//ins:Parameter[@name="TRIGGER_VALUE"]/@value' \
-v "$ACT_NUM" \
soa_triggering.xml