Perl 正则表达式替换,环境变量的评估
Perl Regex Substitution, Evaluation of Environment Variables
我正在尝试将 Perl 的正则表达式替换与评估一起使用,以帮助在 Clearcase -> Git 迁移期间使某些配置文件更加动态。 Clearcase 系统高度依赖于 /vob/ 目录,但我们需要使它更加动态,以使我们的 Jenkins 构建更快乐。我正在尝试降低迁移时破坏 Clearcase 构建的可能性。
我有一个配置文件,它是一个文本文件,每行都有一个路径:
/vob/config/file1
/vob/config/file2
/vob/config/file3
此配置对这些配置文件做了一些额外的事情。 "stuff" 的编排由 Perl 脚本管理。我想要一些环境变量 ("VOB_FOO"),当我 运行 脚本时我可以覆盖它们。
我是 Perl 的新手,所以我想的是使用 Perl 环境变量语法,对其执行正则表达式并在处理文件时在线评估替换结果。
我希望我的新配置文件在文件中具有明确的 $ENV{'VOB_FOO'} 条目,因此文件将变为:
$ENV{'VOB_FOO'}/config/file1 -> /home/me/foo/config/file1
$ENV{'VOB_FOO'}/config/file2 -> /home/me/foo/config/file2
$ENV{'VOB_FOO'}/config/file3 -> /home/me/foo/config/file3
生成的正则表达式替换+求值将变成 (if VOB_FOO=/home/me/foo) :
$ENV{'VOB_FOO'}/config/file1 -> /home/me/foo/config/file1
$ENV{'VOB_FOO'}/config/file2 -> /home/me/foo/config/file2
$ENV{'VOB_FOO'}/config/file3 -> /home/me/foo/config/file3
我的正则表达式匹配得很好,看起来替换有效,但替换的评估部分无效,我需要一些帮助。我匹配成功,但替换结果为:
$ENV{'VOB_FOO'}/config/file1 -> $ENV('VOB_FOO'}/config/file1
$ENV{'VOB_FOO'}/config/file2 -> $ENV('VOB_FOO'}/config/file2
$ENV{'VOB_FOO'}/config/file3 -> $ENV('VOB_FOO'}/config/file3
此评估是否有任何注意事项或我可以通过某种方式使其正常工作?这是我的代码:
## See if we need to substitute an environment variable (e.g., is there a $ENV{} anywhere?)
## s - substitute through regular expressions (s/foo/bar/e)
## e modifier evaluates replacement as perl statement
{
use re 'debugcolor';
# this is for debugging only - I want to substitute
# grab the $ENV('VOB') string from the file and substitute
# I may have multiple environment variables that I have to
# contend with.
my $vob = $ENV{'VOB'};
print $vob;
print "\n";
my $regexp = qr/($ENV\{[\'][\w]*[\']\})/;
if( $second =~ m/$regexp/ )
{
print "Found the regexp; attempting substitution.\n";
$second =~ s/$regexp//e;
}
else
{
print $regexp + "\n";
print $second + "\n";
print "Did not find the regexp\n";
}
}
我也乐于接受关于更好的方法的批评或建议 - 在我努力实现这一目标时,我不受这种方法或代码的束缚。
我想你只需要这个。它不是提取整个表达式,而是获取哈希键并将其用于真实 %ENV
我添加了一个替换,这样哈希键可以用引号或不用引号写入,并且可以有前导空格或尾随空格
$second =~ s/$ENV\{\s*(?|(\w+)|'(\w+)')\s*\}/$ENV{}/g
使用捕获的文字字符串,</code>只有字符(<code>'$'.'E'.'N'...
),首先需要将其制成变量名,然后进行计算。所以,需要两个 evals
use warnings;
use strict;
use feature 'say';
my $var = q(a_$ENV{SHELL}_b); # like $ENV{'VOB'} read from a file
if ( $var =~ s/($ENV\{.*?\})//ee ) { # WARNING: security?
say $var
}
因为 }
从来都不是环境变量名称的一部分,所以我使用非贪婪 .*?
简单地匹配直到 }
的所有内容。 ee
.
的详细解释参见this post
但是,请注意 ee
带有严重的安全考虑,因为它将把给定的字符串变成一个变量 † 和 eval 它,不问的问题。它在污点模式下也不起作用。因此请谨慎使用,并仅在严格控制的情况下使用。
一种更安全的方法是捕获环境变量名称本身,然后通常在替换中对其进行 %ENV
评估,如 建议
$second =~ s/$ENV(\{(.*?)\}/$ENV{}/g;
无论哪种方式,另请注意,您不需要先匹配再替换。
† 危险在于,如果字符串恰好包含任何 code 它是盲目的 eval
-ed
我正在尝试将 Perl 的正则表达式替换与评估一起使用,以帮助在 Clearcase -> Git 迁移期间使某些配置文件更加动态。 Clearcase 系统高度依赖于 /vob/ 目录,但我们需要使它更加动态,以使我们的 Jenkins 构建更快乐。我正在尝试降低迁移时破坏 Clearcase 构建的可能性。
我有一个配置文件,它是一个文本文件,每行都有一个路径:
/vob/config/file1
/vob/config/file2
/vob/config/file3
此配置对这些配置文件做了一些额外的事情。 "stuff" 的编排由 Perl 脚本管理。我想要一些环境变量 ("VOB_FOO"),当我 运行 脚本时我可以覆盖它们。
我是 Perl 的新手,所以我想的是使用 Perl 环境变量语法,对其执行正则表达式并在处理文件时在线评估替换结果。
我希望我的新配置文件在文件中具有明确的 $ENV{'VOB_FOO'} 条目,因此文件将变为:
$ENV{'VOB_FOO'}/config/file1 -> /home/me/foo/config/file1
$ENV{'VOB_FOO'}/config/file2 -> /home/me/foo/config/file2
$ENV{'VOB_FOO'}/config/file3 -> /home/me/foo/config/file3
生成的正则表达式替换+求值将变成 (if VOB_FOO=/home/me/foo) :
$ENV{'VOB_FOO'}/config/file1 -> /home/me/foo/config/file1
$ENV{'VOB_FOO'}/config/file2 -> /home/me/foo/config/file2
$ENV{'VOB_FOO'}/config/file3 -> /home/me/foo/config/file3
我的正则表达式匹配得很好,看起来替换有效,但替换的评估部分无效,我需要一些帮助。我匹配成功,但替换结果为:
$ENV{'VOB_FOO'}/config/file1 -> $ENV('VOB_FOO'}/config/file1
$ENV{'VOB_FOO'}/config/file2 -> $ENV('VOB_FOO'}/config/file2
$ENV{'VOB_FOO'}/config/file3 -> $ENV('VOB_FOO'}/config/file3
此评估是否有任何注意事项或我可以通过某种方式使其正常工作?这是我的代码:
## See if we need to substitute an environment variable (e.g., is there a $ENV{} anywhere?)
## s - substitute through regular expressions (s/foo/bar/e)
## e modifier evaluates replacement as perl statement
{
use re 'debugcolor';
# this is for debugging only - I want to substitute
# grab the $ENV('VOB') string from the file and substitute
# I may have multiple environment variables that I have to
# contend with.
my $vob = $ENV{'VOB'};
print $vob;
print "\n";
my $regexp = qr/($ENV\{[\'][\w]*[\']\})/;
if( $second =~ m/$regexp/ )
{
print "Found the regexp; attempting substitution.\n";
$second =~ s/$regexp//e;
}
else
{
print $regexp + "\n";
print $second + "\n";
print "Did not find the regexp\n";
}
}
我也乐于接受关于更好的方法的批评或建议 - 在我努力实现这一目标时,我不受这种方法或代码的束缚。
我想你只需要这个。它不是提取整个表达式,而是获取哈希键并将其用于真实 %ENV
我添加了一个替换,这样哈希键可以用引号或不用引号写入,并且可以有前导空格或尾随空格
$second =~ s/$ENV\{\s*(?|(\w+)|'(\w+)')\s*\}/$ENV{}/g
使用捕获的文字字符串,</code>只有字符(<code>'$'.'E'.'N'...
),首先需要将其制成变量名,然后进行计算。所以,需要两个 evals
use warnings;
use strict;
use feature 'say';
my $var = q(a_$ENV{SHELL}_b); # like $ENV{'VOB'} read from a file
if ( $var =~ s/($ENV\{.*?\})//ee ) { # WARNING: security?
say $var
}
因为 }
从来都不是环境变量名称的一部分,所以我使用非贪婪 .*?
简单地匹配直到 }
的所有内容。 ee
.
但是,请注意 ee
带有严重的安全考虑,因为它将把给定的字符串变成一个变量 † 和 eval 它,不问的问题。它在污点模式下也不起作用。因此请谨慎使用,并仅在严格控制的情况下使用。
一种更安全的方法是捕获环境变量名称本身,然后通常在替换中对其进行 %ENV
评估,如
$second =~ s/$ENV(\{(.*?)\}/$ENV{}/g;
无论哪种方式,另请注意,您不需要先匹配再替换。
† 危险在于,如果字符串恰好包含任何 code 它是盲目的 eval
-ed