Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 在文本字符串中替换变量_Bash_Shell_Macros_Variable Substitution - Fatal编程技术网

Bash 在文本字符串中替换变量

Bash 在文本字符串中替换变量,bash,shell,macros,variable-substitution,Bash,Shell,Macros,Variable Substitution,bash中的变量中有一个文本字符串,如下所示: filename1.txt filename2.txt varname1 = v1value $(varname1)/filename3.txt $(varname1)/filename4.txt varname2 = $(varname1)/v2value $(varname2)/filename5.txt $(varname2)/filename6.txt 我想替换所有的变量,产生以下结果: filename1.txt filename2

bash中的变量中有一个文本字符串,如下所示:

filename1.txt
filename2.txt

varname1 = v1value
$(varname1)/filename3.txt
$(varname1)/filename4.txt

varname2 = $(varname1)/v2value
$(varname2)/filename5.txt
$(varname2)/filename6.txt
我想替换所有的变量,产生以下结果:

filename1.txt
filename2.txt

v1value/filename3.txt
v1value/filename4.txt

v1value/v2value/filename5.txt
v1value/v2value/filename6.txt

有人能提出一个干净的方法在shell中实现这一点吗?

我使用
m4
找到了一个合理的解决方案:

function make_substitutions() {
    # first all $(varname)s are replaced with ____varname____
    # then each assignment statement is replaced with an m4 define macro
    # finally this text is then passed through m4

    echo "$1" |\
    sed 's/\$(\([[:alnum:]][[:alnum:]]*\))/____\1____/' | \
    sed 's/ *\([[:alnum:]][[:alnum:]]*\) *= *\(..*\)/define(____\1____, \2)/' | \
    m4
}
或许

echo "$string" | perl -nlE 'm/(\w+)\s*=\s*(.*)(?{$h{$1}=$2})/&&next;while(m/\$\((\w+)\)/){$x=$1;s/\$\($x\)/$h{$x}/e};say$_'
印刷品

filename1.txt
filename2.txt

v1value/filename3.txt
v1value/filename4.txt

v1value/v2value/filename5.txt
v1value/v2value/filename6.txt
在awk中:

BEGIN {
    FS = "[[:space:]]*=[[:space:]]*"
}

NF > 1 {
    map[$1] = $2
    next;
}

function replace(     count)
{
    for (key in map) {
        count += gsub("\\$\\("key"\\)", map[key])
    }

    return count
}

{
    while (replace() > 0) {}
    print
}
在卢阿:

local map = {}

--for line in io.lines("file.in") do -- To read from a file.
for line in io.stdin:lines() do -- To read from standard input.
    local key, value = line:match("^(%w*)%s*=%s*(.*)$")
    if key then
        map[key] = value
    else
        local count
        while count ~= 0 do
            line, count = line:gsub("%$%(([^)]*)%)", map)
        end
        print(line)
    end
end

这个文件有多大?这类问题实际上可以通过一个好的文本编辑器手动更快地解决,除非文件真的很大。这只是一个示例。实际上有几百个这样的文件,每个文件中有0到20个替换。您可以将这种模式用于任何允许这种运行时计算的语言或模板/宏系统。您甚至可以通过一些努力(和消毒)来使用shell本身。一个(可能是单程)awk解决方案也应该相当简单。