2010-05-14 92 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中的我的「安全編程技巧」一章,在此討論此問題,以及在此情況下可能要使用的污點檢查。

相關問題