假设我有一个模板文本文件,其大部分内容都是静态的,但有一些变量。 E.g。
My favorite site is ${FAV_SITE}
假设FAV_SITE设置为stackoverflow.com:
export FAV_SITE=stackoverflow.com
如何在解决了vars的情况下向STDOUT打印文件内容,即
My favorite site is stackoverflow.com
不使用像sed或awk这样的奇特工具?
答案 0 :(得分:2)
这是一个几乎无足轻重的Perl工作。
#!/usr/bin/env perl
#
# Substitute environment variables into text
use strict;
use warnings;
while (<>)
{
while (m/\${(\w+)}/g)
{
my $env = $1;
if (defined $ENV{$env})
{
my $sub = $ENV{$env};
s/\${$env}/$sub/g;
}
}
print;
}
如果未定义环境变量,则会保持${VARIABLE}
符号不变。
例如,在输入数据上:
This is ${HOME} and so is this (${HOME}) and that's ${USER} and that's all.
This is ${UNDEFINED} and that is ${UNDEF} too.
输出可能是:
This is /work4/jleffler and so is this (/work4/jleffler) and that's jleffler and that's all.
This is ${UNDEFINED} and that is ${UNDEF} too.
Perl可能不是紧凑的,但是如果你知道读操作符<>
以及匹配,替换和打印操作符在默认变量上工作,它或多或少是可理解的,$_
。
在RHEL 5 Linux上使用Perl 5.12.1(自制)(不要问),我用过:
$ cat x3
This is ${UNDEFINED} and that is ${UNDEF} too.
This is ${HOME} and so is this (${HOME}) and that's ${USER} and that's all.
$ perl subenv.pl x3
This is ${UNDEFINED} and that is ${UNDEF} too.
This is /work4/jleffler and so is this (/work4/jleffler) and that's jleffler and that's all.
$
如果使用here文档创建模板,请小心; shell也将扩展这些变量。
我还在RHEL机器上的/usr/bin/perl
中找到了Perl 5.8.8并产生了相同的输出。我还在Mac OS X 10.7.5上检查了Perl 5.16.0,并得到了相应的结果(不同的主目录)。我还在HP-UX 11.00计算机上找到了Perl 5.6.1,其中${USER}
未在环境中设置,但它正确替换了${HOME}
。
答案 1 :(得分:1)
你能把模板文件变成一个bash脚本吗?
#!/bin/bash
# This is a template, execute it to get interpolated text:
cat <<HERE
My favorite site is ${FAV_SITE}
HERE
使用示例:
export FAV_SITE=stackoverflow.com
bash ./template.txt.sh
(哦,您可能需要访问reddit.com)
答案 2 :(得分:0)
始终警惕eval
,但是:
while read l; do eval echo "\"$l\""; done < input-file
如果您控制输入,则仅使用此选项。例如,如果输入包含
像"; rm -rf /"
这样的行,运行这个脚本是非常不幸的。
答案 3 :(得分:0)
使用Perl:
#!/usr/bin/perl
use strict;
my $inFile = $ARGV[0];
print "\nInput File=".$inFile;
open(FILEHANDLE, "<$inFile") || die("Could not open file");
my @fileLines = <FILEHANDLE>;
my $rslt;
foreach my $line(@fileLines)
{
#chomp($line);
#print "\nLINE BEFORE=".$line;
while($line =~ m/(\${\w+})/g)
{
if($1)
{
my $plchldr = $1;
my $varName = $plchldr;
$varName =~ s/(\$|{|})//g;
my $varVal = $ENV{$varName};
if($varVal)
{
$line =~ s/\Q$plchldr/$varVal/g;
}
}
}
$rslt .= $line;
#print "\nLINE AFTER=".$line;
}
print "\nRESULT = ".$rslt;
close(FILEHANDLE);
print "\n";
exit(0);