我确信有一种非常简单的方法可以做到这一点。我正在尝试获取一个包含一些环境变量的文件并对其进行扩展,以便将已知的文件扩展为其值,而不是那些不被保留的文件。
例如,如果我的文件包含以下内容:
${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预处理器替换环境中的所有对。这里有几个鱼子酱:
答案 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
根据需要修改输出格式:)