扩展文件中的已知env并留下其他文件

时间:2011-06-17 11:07:52

标签: linux bash shell

我确信有一种非常简单的方法可以做到这一点。我正在尝试获取一个包含一些环境变量的文件并对其进行扩展,以便将已知的文件扩展为其值,而不是那些不被保留的文件。

例如,如果我的文件包含以下内容:

${I_EXIST}
${I_ALSO_EXIST}
${I_DONT_EXIST}

这将扩展为:

existValue
alsoExistValue
${I_DONT_EXIST}

我理想的是希望尽可能简单地这样做,所以我不想使用sed,awk或perl进行复杂的替换。我正在考虑类似于“Here”文件的东西,但除了我无法正确获得语法之外,它还会删除任何不会扩展的内容。 E.g:

cat <<EOF
> ${I_EXIST}
> ${I_ALSO_EXIST}
> ${I_DONT_EXIST}
EOF
existValue
alsoExistValue

(即最后一个值扩展为空)

更新

真的应该明确我在考虑每行可能有多个替换。我确实找到了这样做的一种方法,如果我们没有对文件中出现的变量${MYVAR}感到困惑,但可能MYVAR会这样做:

m4 $( env | sed 's/\([A-Za-z0-9]*\)=\([\/A-Za-z_0-9:|%*. -@]*\)/-D\1=\2' ) myfile

这使用M4预处理器替换环境中的所有对。这里有几个鱼子酱:

  1. 对于reg exp的内容感到抱歉。它看起来很讨厌,我敢肯定有更好的表达方式。如果我的env vars中有空格或任何不在集合中的异常字符,我发现了问题。
  2. 当然这是一个直接的替换工具(我试图避免),所以当你不希望它发生时,变量可能会被取代。

3 个答案:

答案 0 :(得分:3)

#!/bin/bash

while read a;
do
    n=$(eval echo $a)

    if [[ "$n" == "" ]]
    then
        echo $a
    else
        echo $n
    fi

done < input

将此作为输入

${HOME}
${nonexistent}

给出

/home/myuser
${nonexistent}

答案 1 :(得分:2)

易于阅读?也许不吧。虽然它很短并且有效: - )

while read r; do
echo $(eval echo ${r%\}}:-'$r'\})
done < input

魔术使用: http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

修改:进一步说明,我希望它能让有些感觉。

我们使用两种技术;来自上述文档:

  

$ {parameter:-word}如果参数是   unset或null,扩展单词   被取代。否则,价值   参数被替换。

  

$ {参数%字}   这个词被扩展为产生一个   模式就像文件名扩展一样。   如果模式匹配尾随   扩展值的一部分   参数,然后是结果   扩展是参数的值   具有最短的匹配模式   ('%'的情况)或最长的匹配   模式('%%'案例)已删除。 ...

我们使用输入就是我们可以在shell中使用的事实,我们有${FOOBAR}但需要${FOOBAR:-'${FOOBAR}'}(单引号以避免扩展)。

# echo ${doesntexist:-Hello}
Hello
# doesexist=World
# echo ${doesexist:-Will not be printed}
World

所以我们需要注入的是:-'${FOOBAR}'

为了达到这个目的,我们在最后修剪},添加字符串,然后再放回另一个}

# echo $r
${FOOBAR}
# echo ${r%\}}
${FOOBAR

最终的\}并不是必需的,因为在这种情况下它没有开始,但最好是明确地逃避它。 (就像你将echo \*转义一样,即使没有任何匹配文件的echo *给你一个文字*)。

Edit2 :这当然没有考虑到你想在一行中支持多个变量;或其中包含其他内容的任何行。

答案 2 :(得分:1)

while read name; do echo "$name = " $(eval echo $name); done < file_with_vars.txt

将回应所有知道的变量。

e.g。 在我的名为vv

的文件中
${PATH}
${HAVENOT}
${LOCALE}

将打印

${PATH} =  /usr/local/narwhal/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:~/bin
${HAVENOT} = 
${LOCALE} =  UTF-8

根据需要修改输出格式:)