我有一个Perl脚本,可以完成扩展Unix环境变量的工作。脚本运行正常。脚本如下:
# I know this should not be typed here. This is here just for testing.
@ENV{qw(LKUP_DIR DATA_DIR CTRL_DIR MMM)} = qw(/appl1/TSS/lkup /appl1/TSS/data /appl1/TSS/ctrl Oct);
while ( <DATA> )
{
my $line=$_;
chomp $line;
$line =~ s{\$(\w+)}{ exists $ENV{$1} ? $ENV{$1} : '$'.$1 }ge;
$line =~ s{\$\{(\w+)\}}{ exists $ENV{$1} ? $ENV{$1} : '${'.$1.'}' }ge;
print "$line\n";
}
__DATA__
${LKUP_DIR}/lookup_file.txt
${CTRL_DIR}/ctrl_file_$MMMM.txt
$CTRL_DIR/ctrl_file_$MMM.txt
我想将此脚本转换为单行,但我不确定如何处理上述脚本中使用的正则表达式中$周围的单引号。我尝试了以下,但当然它不起作用:
perl -lne '$line=$_; $line =~ s{\$(\w+)}{ exists $ENV{$1} ? $ENV{$1} : '$'.$1 }ge; $line =~ s{\$\{(\w+)\}}{ exists $ENV{$1} ? $ENV{$1} : '${'.$1.'}' }ge; print "$line";' DATA.txt
有什么建议吗? (我想只在Perl中这样做。)
答案 0 :(得分:2)
我同意@Mat:这似乎是一个坏主意。这将只是一行,但你的可读性会下降。只是想想你可能会在一年之后进行编辑,并且仍然试着了解一个班轮的作用。
但无论如何,在Perl中,您可以使用q/STRING/
代替'STRING'
。
perl -lne '$line=$_; $line =~ s{\$(\w+)}{ exists $ENV{$1} ? $ENV{$1} : q/$/.$1 }ge; $line =~ s{\$\{(\w+)\}}{ exists $ENV{$1} ? $ENV{$1} : q/${/.$1.q/}/ }ge; print "$line";' DATA.txt
答案 1 :(得分:2)
这是一个更简洁的脚本版本。一个显着的区别是我使用//
而不是exists
。我认为,环境变量所涉及的差异可以忽略不计。如果环境变量存在但未定义,那么它是什么?如果它确实是未定义的,那么在perl打印它时会引发警告。
perl -wpe 's#\${?(\w+)}?# $ENV{$1} // $& #ge;' DATA.txt
如果您仍然坚持使用exist
,只需使用:
perl -wpe 's#\${?(\w+)}?# exists $ENV{$1} ? $ENV{$1} : $& #ge;' DATA.txt
我做了什么:
$line
-l
选项-n
print
和-p
{}
}?
作为可选匹配$&
- 完整匹配 - 而不是试图拼图部分
比赛重新组合