2010-05-14 229 views
4

说我有一个环境变量myvar如何在Perl字符串中插入文字 t和 n?

myvar=\tapple\n 

当下面的命令将打印出这个变量

perl -e 'print "$ENV{myvar}"' 

我会从字面上\tapple\n,不过,我想那些控制字符进行评估和没有逃脱。我将如何实现它?

在真实世界$ENV居住在替代,但我希望答案会覆盖。

+0

备份一个步骤,为什么你的环境变量中有这些序列? – 2010-05-15 23:12:32

+0

@brian d foy:因为它们来自文本文件,多行和格式。 – Pablo 2010-05-16 00:59:15

回答

3

使用eval

perl -e 'print eval qq{"$ENV{myvar}"}' 

UPD:您还可以使用替代与ee开关,这是更安全:

perl -e '(my $s = $ENV{myvar}) =~ s/(\\n|\\t)/"qq{$1}"/gee; print $s' 
+2

从环境变量直接评估代码?听起来像是一种安全风险。 – rjh 2010-05-14 16:56:41

+0

这有点冒险,但它似乎是迈克尔需要的答案。 – modz0r 2010-05-14 19:22:40

+0

不要这样做。字符串eval通常是您需要了解更多Perl的标志。 :) – 2010-05-14 23:03:38

2

你或许应该使用String::Escape

use String::Escape qw(unbackslash); 

my $var = unbackslash($ENV{'myvar'}); 

unbackslash反转义发现的任何字符串转义序列,把它们变成它们所代表的字符。如果您只想明确地只翻译\n\t,那么您可能必须自己执行s修改,如this answer

+1

我唯一担心的是'不可打印'的翻译可能比你愿意接受的要多得多。 – 2010-05-14 23:02:35

+0

这是一个很好的观点。利美反映说... – darch 2010-05-15 07:18:36

+0

这个答案听起来像他想做的事情相反。他写道:“我希望对这些控制字符进行评估,而不是逃脱。”所以它看起来像是“不反弹”是他希望从该模块中获得的功能。 – jrockway 2010-05-15 22:45:58

1

对于包含\的字符序列,没有什么特别的特别之处。如果要替换的字符的一个序列另一个,这是非常简单的用Perl做:

my %sequences = (
     '\\t' => "\t", 
     '\\n' => "\n", 
     'foo' => 'bar', 
    ); 

my $string = '\\tstring fool string\\tfoo\\n'; 

print "Before: [$string]\n"; 
$string =~ s/\Q$_/$sequences{$_}/g for (keys %sequences); 
print "After: [$string]\n"; 

与\唯一的技巧是跟踪时代时的Perl认为它是一个转义字符。

Before: [\tstring fool string\tfoo\n] 
After: [ string barl string bar 
] 

然而,正如darch notes,你可能只能够使用String::Escape

请注意,当您从环境变量中获取值时,您必须非常小心。我不愿意使用String::Escape,因为它可能会比你愿意翻译更多。安全的方法是只扩展你明确想要允许的特定值。请参阅Mastering Perl中的我的“安全编程技巧”一章,在此讨论此问题,以及在此情况下可能要使用的污点检查。

相关问题