繁体   English   中英

Perl一线式扩展Unix环境变量

[英]Perl one-liner to expand Unix environment variables

我有一个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中这样做。)

我同意@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

这是脚本的更简洁版本。 一个显着的区别是我使用//代替了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并用-p print
  • 更改替换上的定界符以不必转义{}
  • 通过添加}?组合正则表达式}? 作为可选匹配
  • 使用$& -整个比赛-而不是尝试将比赛的各个部分重新拼合在一起

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM