如何替换文本文件中的 ${} 占位符?

发布于 2024-07-11 11:17:44 字数 158 浏览 13 评论 0 原文

我想将“模板”文件的输出通过管道传输到 MySQL,该文件散布有诸如 ${dbName} 之类的变量。 用于替换这些实例并将输出转储到标准输出的命令行实用程序是什么?

输入文件被认为是安全的,但可能存在错误的替换定义。 执行替换应避免执行意外的代码。

I want to pipe the output of a "template" file into MySQL, the file having variables like ${dbName} interspersed. What is the command line utility to replace these instances and dump the output to standard output?

The input file is considered to be safe, but faulty substitution definitions could exist. Performing the replacement should avoid performing unintended code execution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

花开柳相依 2024-07-18 11:17:44

更新:尝试 envsubst

这是来自 yottatsa 的类似问题的解决方案,该解决方案仅替换 $VAR 或 ${ 等变量 当然,

i=32 word=foo envsubst < template.txt

如果iword在你的环境中,那么它只是

envsubst < template.txt

在我的Mac上,看起来它是作为一部分安装的gettextMacGPG2

旧答案:尝试 eval

这是对 mogsie 在类似的问题上,我的解决方案不需要您转义双引号,mogsie 需要转义,但他是一个衬垫!

eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null

这两种解决方案的强大之处在于,您只能获得几种通常不会发生的 shell 扩展 $((...))、`...` 和 $(...),尽管反斜杠 在这里是一个转义字符,但是您不必担心解析有错误,并且它可以很好地处理多行。

Update: Try envsubst

Here is a solution from yottatsa on a similar question that only does replacement for variables like $VAR or ${VAR}, and is a brief one-liner

i=32 word=foo envsubst < template.txt

Of course if i and word are in your environment, then it is just

envsubst < template.txt

On my Mac it looks like it was installed as part of gettext and from MacGPG2

Old Answer: Try eval

Here is an improvement to the solution from mogsie on a similar question, my solution does not require you to escape double quotes, mogsie's does, but his is a one liner!

eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null

The power on these two solutions is that you only get a few types of shell expansions that don't occur normally $((...)), `...`, and $(...), though backslash is an escape character here, but you don't have to worry that the parsing has a bug, and it does multiple lines just fine.

橘亓 2024-07-18 11:17:44

Sed

鉴于 template.txt:

The number is ${i}
The word is ${word}

我们只需说:

sed -e "s/\${i}/1/" -e "s/\${word}/dog/" template.txt

感谢 Jonathan Leffler 提供了将多个 -e 参数传递给同一个 sed 调用的提示。

Sed!

Given template.txt:

The number is ${i}
The word is ${word}

we just have to say:

sed -e "s/\${i}/1/" -e "s/\${word}/dog/" template.txt

Thanks to Jonathan Leffler for the tip to pass multiple -e arguments to the same sed invocation.

回首观望 2024-07-18 11:17:44

使用/bin/sh。 创建一个设置变量的小 shell 脚本,然后使用 shell 本身解析模板。 像这样(编辑以正确处理换行符):

文件 template.txt:

the number is ${i}
the word is ${word}

文件 script.sh:

#!/bin/sh

#Set variables
i=1
word="dog"

#Read in template one line at the time, and replace variables (more
#natural (and efficient) way, thanks to Jonathan Leffler).
while read line
do
    eval echo "$line"
done < "./template.txt"

输出:

#sh script.sh
the number is 1
the word is dog

Use /bin/sh. Create a small shell script that sets the variables, and then parse the template using the shell itself. Like so (edit to handle newlines correctly):

File template.txt:

the number is ${i}
the word is ${word}

File script.sh:

#!/bin/sh

#Set variables
i=1
word="dog"

#Read in template one line at the time, and replace variables (more
#natural (and efficient) way, thanks to Jonathan Leffler).
while read line
do
    eval echo "$line"
done < "./template.txt"

Output:

#sh script.sh
the number is 1
the word is dog
缪败 2024-07-18 11:17:44

鉴于最近的兴趣,我又在考虑这个问题,我认为我最初想到的工具是 m4,自动工具的宏处理器。 因此,您可以使用以下命令来代替我最初指定的变量:

$echo 'I am a DBNAME' | m4 -DDBNAME="database name"

I was thinking about this again, given the recent interest, and I think that the tool that I was originally thinking of was m4, the macro processor for autotools. So instead of the variable I originally specified, you'd use:

$echo 'I am a DBNAME' | m4 -DDBNAME="database name"
也只是曾经 2024-07-18 11:17:44

创建rendertemplate.sh

#!/usr/bin/env bash

eval "echo \"$(cat $1)\""

template.tmpl

Hello, ${WORLD}
Goodbye, ${CHEESE}

渲染模板:

$ export WORLD=Foo
$ CHEESE=Bar ./rendertemplate.sh template.tmpl 
Hello, Foo
Goodbye, Bar

Create rendertemplate.sh:

#!/usr/bin/env bash

eval "echo \"$(cat $1)\""

And template.tmpl:

Hello, ${WORLD}
Goodbye, ${CHEESE}

Render the template:

$ export WORLD=Foo
$ CHEESE=Bar ./rendertemplate.sh template.tmpl 
Hello, Foo
Goodbye, Bar
网白 2024-07-18 11:17:44

template.txt

Variable 1 value: ${var1}
Variable 2 value: ${var2}

data.sh

#!/usr/bin/env bash
declare var1="value 1"
declare var2="value 2"

parser.sh

#!/usr/bin/env bash

# args
declare file_data=$1
declare file_input=$2
declare file_output=$3

source $file_data
eval "echo \"$(< $file_input)\"" > $file_output

./parser.sh data.sh template.txt parsed_file.txt

parsed_file.txt

Variable 1 value: value 1
Variable 2 value: value 2

template.txt

Variable 1 value: ${var1}
Variable 2 value: ${var2}

data.sh

#!/usr/bin/env bash
declare var1="value 1"
declare var2="value 2"

parser.sh

#!/usr/bin/env bash

# args
declare file_data=$1
declare file_input=$2
declare file_output=$3

source $file_data
eval "echo \"$(< $file_input)\"" > $file_output

./parser.sh data.sh template.txt parsed_file.txt

parsed_file.txt

Variable 1 value: value 1
Variable 2 value: value 2
苏大泽ㄣ 2024-07-18 11:17:44

这是我基于之前答案的 perl 解决方案,替换了环境变量:

perl -p -e 's/\$\{(\w+)\}/(exists $ENV{$1}?$ENV{$1}:"missing variable $1")/eg' < infile > outfile

here's my solution with perl based on former answer, replaces environment variables:

perl -p -e 's/\$\{(\w+)\}/(exists $ENV{$1}?$ENV{$1}:"missing variable $1")/eg' < infile > outfile
独行侠 2024-07-18 11:17:44

这是一个强大的 Bash 函数,尽管使用了eval,但应该可以安全使用。

输入文本中的所有 ${varName} 变量引用都会根据调用 shell 的变量进行扩展。

没有其他内容被扩展:名称​​未包含在 {...} 中的变量引用(例如 $varName),也不是命令替换($(...) 和旧语法 `...`),也不是算术替换($((.. .)) 和旧语法 $[...])。

要将 $ 视为文字,请使用 \ 将其转义; 例如:\${HOME}

请注意,仅通过 stdin 接受输入。

示例:

$ expandVarsStrict <<<'$HOME is "${HOME}"; `date` and \$(ls)' # only ${HOME} is expanded
$HOME is "/Users/jdoe"; `date` and $(ls)

函数源代码:

expandVarsStrict(){
  local line lineEscaped
  while IFS= read -r line || [[ -n $line ]]; do  # the `||` clause ensures that the last line is read even if it doesn't end with \n
    # Escape ALL chars. that could trigger an expansion..
    IFS= read -r -d '' lineEscaped < <(printf %s "$line" | tr '`([

函数假设没有 0x10x20x3 0x4 控制字符出现在输入中,因为这些字符。 在内部使用 - 由于该函数处理文本,这应该是一个安全的假设。

'\1\2\3\4') # ... then selectively reenable ${ references lineEscaped=${lineEscaped//

函数假设没有 0x10x20x3 0x4 控制字符出现在输入中,因为这些字符。 在内部使用 - 由于该函数处理文本,这应该是一个安全的假设。

\4'{/\${} # Finally, escape embedded double quotes to preserve them. lineEscaped=${lineEscaped//\"/\\\"} eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([

函数假设没有 0x10x20x3 0x4 控制字符出现在输入中,因为这些字符。 在内部使用 - 由于该函数处理文本,这应该是一个安全的假设。

done }

函数假设没有 0x10x20x3 0x4 控制字符出现在输入中,因为这些字符。 在内部使用 - 由于该函数处理文本,这应该是一个安全的假设。

Here's a robust Bash function that - despite using eval - should be safe to use.

All ${varName} variable references in the input text are expanded based on the calling shell's variables.

Nothing else is expanded: neither variable references whose names are not enclosed in {...} (such as $varName), nor command substitutions ($(...) and legacy syntax `...`), nor arithmetic substitutions ($((...)) and legacy syntax $[...]).

To treat a $ as a literal, \-escape it; e.g.:\${HOME}

Note that input is only accepted via stdin.

Example:

$ expandVarsStrict <<<'$HOME is "${HOME}"; `date` and \$(ls)' # only ${HOME} is expanded
$HOME is "/Users/jdoe"; `date` and $(ls)

Function source code:

expandVarsStrict(){
  local line lineEscaped
  while IFS= read -r line || [[ -n $line ]]; do  # the `||` clause ensures that the last line is read even if it doesn't end with \n
    # Escape ALL chars. that could trigger an expansion..
    IFS= read -r -d '' lineEscaped < <(printf %s "$line" | tr '`([

The function assumes that no 0x1, 0x2, 0x3, and 0x4 control characters are present in the input, because those chars. are used internally - since the function processes text, that should be a safe assumption.

'\1\2\3\4') # ... then selectively reenable ${ references lineEscaped=${lineEscaped//

The function assumes that no 0x1, 0x2, 0x3, and 0x4 control characters are present in the input, because those chars. are used internally - since the function processes text, that should be a safe assumption.

\4'{/\${} # Finally, escape embedded double quotes to preserve them. lineEscaped=${lineEscaped//\"/\\\"} eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([

The function assumes that no 0x1, 0x2, 0x3, and 0x4 control characters are present in the input, because those chars. are used internally - since the function processes text, that should be a safe assumption.

done }

The function assumes that no 0x1, 0x2, 0x3, and 0x4 control characters are present in the input, because those chars. are used internally - since the function processes text, that should be a safe assumption.

只有影子陪我不离不弃 2024-07-18 11:17:44

我建议使用类似 Sigil 的东西:
https://github.com/gliderlabs/sigil

它被编译为单个二进制文件,因此非常简单安装在系统上。

然后你可以做一个简单的一行,如下所示:

cat my-file.conf.template | sigil -p $(env) > my-file.conf

这比 eval 更安全,并且比使用正则表达式或 sed 更容易

I would suggest using something like Sigil:
https://github.com/gliderlabs/sigil

It is compiled to a single binary, so it's extremely easy to install on systems.

Then you can do a simple one-liner like the following:

cat my-file.conf.template | sigil -p $(env) > my-file.conf

This is much safer than eval and easier then using regex or sed

三五鸿雁 2024-07-18 11:17:44

这是一种让 shell 为您进行替换的方法,就好像文件的内容是在双引号之间键入的一样。

使用带有内容的 template.txt 示例:

The number is ${i}
The word is ${word}

以下行将导致 shell 插入 template.txt 的内容并将结果写入标准输出。

i='1' word='dog' sh -c 'echo "'"$(cat template.txt)"'"'

说明:

  • iword 作为环境变量传递给 sh 的执行。
  • sh 执行传递给它的字符串的内容。
  • 相邻写入的字符串成为一个字符串,该字符串是:
    • 'echo "' + "$(cat template.txt)" + '"'
  • 因为替换是在 ", "$(cat template.txt)" 成为cat template.txt的输出。
  • 因此sh -c 执行的命令 变为:
    • echo "数字是 ${i}\n单词是 ${word}",
    • 其中 iword 是指定的环境变量。

Here is a way to get the shell to do the substitution for you, as if the contents of the file were instead typed between double quotes.

Using the example of template.txt with contents:

The number is ${i}
The word is ${word}

The following line will cause the shell to interpolate the contents of template.txt and write the result to standard out.

i='1' word='dog' sh -c 'echo "'"$(cat template.txt)"'"'

Explanation:

  • i and word are passed as environment variables scopped to the execution of sh.
  • sh executes the contents of the string it is passed.
  • Strings written next to one another become one string, that string is:
    • 'echo "' + "$(cat template.txt)" + '"'
  • Since the substitution is between ", "$(cat template.txt)" becomes the output of cat template.txt.
  • So the command executed by sh -c becomes:
    • echo "The number is ${i}\nThe word is ${word}",
    • where i and word are the specified environment variables.
夜无邪 2024-07-18 11:17:44

如果您愿意使用 Perl,这将是我的建议。 尽管可能有一些 sed 和/或 AWK 专家可能知道如何更轻松地做到这一点。 如果您有一个更复杂的映射,不仅仅是 dbName 来替换,您可以很容易地扩展它,但此时您也可以将其放入标准 Perl 脚本中。

perl -p -e 's/\$\{dbName\}/testdb/s' yourfile | mysql

一个简短的 Perl 脚本,用于执行稍微复杂的操作(处理多个键):

#!/usr/bin/env perl
my %replace = ( 'dbName' => 'testdb', 'somethingElse' => 'fooBar' );
undef $/;
my $buf = <STDIN>;
$buf =~ s/\$\{$_\}/$replace{$_}/g for keys %replace;
print $buf;

如果将上述脚本命名为替换脚本,则可以按如下方式使用它:

replace-script < yourfile | mysql

If you are open to using Perl, that would be my suggestion. Although there are probably some sed and/or AWK experts that probably know how to do this much easier. If you have a more complex mapping with more than just dbName for your replacements you could extend this pretty easily, but you might just as well put it into a standard Perl script at that point.

perl -p -e 's/\$\{dbName\}/testdb/s' yourfile | mysql

A short Perl script to do something slightly more complicated (handle multiple keys):

#!/usr/bin/env perl
my %replace = ( 'dbName' => 'testdb', 'somethingElse' => 'fooBar' );
undef $/;
my $buf = <STDIN>;
$buf =~ s/\$\{$_\}/$replace{$_}/g for keys %replace;
print $buf;

If you name the above script as replace-script, it could then be used as follows:

replace-script < yourfile | mysql
千鲤 2024-07-18 11:17:44

文件.tpl:

The following bash function should only replace ${var1} syntax and ignore 
other shell special chars such as `backticks` or $var2 or "double quotes". 
If I have missed anything - let me know.

脚本.sh:

template(){
    # usage: template file.tpl
    while read -r line ; do
            line=${line//\"/\\\"}
            line=${line//\`/\\\`}
            line=${line//\$/\\\$}
            line=${line//\\\${/\${}
            eval "echo \"$line\""; 
    done < ${1}
}

var1="*replaced*"
var2="*not replaced*"

template file.tpl > result.txt

file.tpl:

The following bash function should only replace ${var1} syntax and ignore 
other shell special chars such as `backticks` or $var2 or "double quotes". 
If I have missed anything - let me know.

script.sh:

template(){
    # usage: template file.tpl
    while read -r line ; do
            line=${line//\"/\\\"}
            line=${line//\`/\\\`}
            line=${line//\$/\\\$}
            line=${line//\\\${/\${}
            eval "echo \"$line\""; 
    done < ${1}
}

var1="*replaced*"
var2="*not replaced*"

template file.tpl > result.txt
各自安好 2024-07-18 11:17:44

我在想知道同样的事情时发现了这个线程。 这启发了我(小心反引号)

$ echo $MYTEST
pass!
$ cat FILE
hello $MYTEST world
$ eval echo `cat FILE`
hello pass! world

I found this thread while wondering the same thing. It inspired me to this (careful with the backticks)

$ echo $MYTEST
pass!
$ cat FILE
hello $MYTEST world
$ eval echo `cat FILE`
hello pass! world
瘫痪情歌 2024-07-18 11:17:44

这里有很多选择,但我想我会把我的扔到堆上。 它是基于 Perl 的,仅针对 ${...} 形式的变量,将要处理的文件作为参数并在 stdout 上输出转换后的文件:

use Env;
Env::import();

while(<>) { $_ =~ s/(\${\w+})/$1/eeg; $text .= $_; }

print "$text";

当然,我不是一个真正的 Perl 人,所以很容易一个致命的缺陷(不过对我有用)。

Lots of choices here, but figured I'd toss mine on the heap. It is perl based, only targets variables of the form ${...}, takes the file to process as an argument and outputs the converted file on stdout:

use Env;
Env::import();

while(<>) { $_ =~ s/(\${\w+})/$1/eeg; $text .= $_; }

print "$text";

Of course I'm not really a perl person, so there could easily be a fatal flaw (works for me though).

西瑶 2024-07-18 11:17:44

如果您可以控制配置文件格式,则可以在 bash 本身中完成。 您只需要获取(“.”)配置文件而不是对其进行 subshel​​l。 这确保了变量是在当前 shell 的上下文中创建的(并继续存在),而不是在子 shell 中创建(当子 shell 退出时,变量会消失)。

$ cat config.data
    export parm_jdbc=jdbc:db2://box7.co.uk:5000/INSTA
    export parm_user=pax
    export parm_pwd=never_you_mind

$ cat go.bash
    . config.data
    echo "JDBC string is " $parm_jdbc
    echo "Username is    " $parm_user
    echo "Password is    " $parm_pwd

$ bash go.bash
    JDBC string is  jdbc:db2://box7.co.uk:5000/INSTA
    Username is     pax
    Password is     never_you_mind

如果您的配置文件不能是 shell 脚本,您可以在执行之前“编译”它(编译取决于您的输入格式)。

$ cat config.data
    parm_jdbc=jdbc:db2://box7.co.uk:5000/INSTA # JDBC URL
    parm_user=pax                              # user name
    parm_pwd=never_you_mind                    # password

$ cat go.bash
    cat config.data
        | sed 's/#.*$//'
        | sed 's/[ \t]*$//'
        | sed 's/^[ \t]*//'
        | grep -v '^

在你的具体情况下,你可以使用类似的东西:

$ cat config.data
    export p_p1=val1
    export p_p2=val2
$ cat go.bash
    . ./config.data
    echo "select * from dbtable where p1 = '$p_p1' and p2 like '$p_p2%' order by p1"
$ bash go.bash
    select * from dbtable where p1 = 'val1' and p2 like 'val2%' order by p1

然后将 go.bash 的输出通过管道传输到 MySQL 中,瞧,希望你不会破坏你的数据库:-)。

| sed 's/^/export ' >config.data-compiled . config.data-compiled echo "JDBC string is " $parm_jdbc echo "Username is " $parm_user echo "Password is " $parm_pwd $ bash go.bash JDBC string is jdbc:db2://box7.co.uk:5000/INSTA Username is pax Password is never_you_mind

在你的具体情况下,你可以使用类似的东西:


然后将 go.bash 的输出通过管道传输到 MySQL 中,瞧,希望你不会破坏你的数据库:-)。

It can be done in bash itself if you have control of the configuration file format. You just need to source (".") the configuration file rather than subshell it. That ensures the variables are created in the context of the current shell (and continue to exist) rather than the subshell (where the variable disappear when the subshell exits).

$ cat config.data
    export parm_jdbc=jdbc:db2://box7.co.uk:5000/INSTA
    export parm_user=pax
    export parm_pwd=never_you_mind

$ cat go.bash
    . config.data
    echo "JDBC string is " $parm_jdbc
    echo "Username is    " $parm_user
    echo "Password is    " $parm_pwd

$ bash go.bash
    JDBC string is  jdbc:db2://box7.co.uk:5000/INSTA
    Username is     pax
    Password is     never_you_mind

If your config file cannot be a shell script, you can just 'compile' it before executing thus (the compilation depends on your input format).

$ cat config.data
    parm_jdbc=jdbc:db2://box7.co.uk:5000/INSTA # JDBC URL
    parm_user=pax                              # user name
    parm_pwd=never_you_mind                    # password

$ cat go.bash
    cat config.data
        | sed 's/#.*$//'
        | sed 's/[ \t]*$//'
        | sed 's/^[ \t]*//'
        | grep -v '^

In your specific case, you could use something like:

$ cat config.data
    export p_p1=val1
    export p_p2=val2
$ cat go.bash
    . ./config.data
    echo "select * from dbtable where p1 = '$p_p1' and p2 like '$p_p2%' order by p1"
$ bash go.bash
    select * from dbtable where p1 = 'val1' and p2 like 'val2%' order by p1

Then pipe the output of go.bash into MySQL and voila, hopefully you won't destroy your database :-).

| sed 's/^/export ' >config.data-compiled . config.data-compiled echo "JDBC string is " $parm_jdbc echo "Username is " $parm_user echo "Password is " $parm_pwd $ bash go.bash JDBC string is jdbc:db2://box7.co.uk:5000/INSTA Username is pax Password is never_you_mind

In your specific case, you could use something like:


Then pipe the output of go.bash into MySQL and voila, hopefully you won't destroy your database :-).

蓦然回首 2024-07-18 11:17:44

对可能的多个文件进行适当的 Perl 编辑,并进行备份。

  perl -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : ""/eg' \
    -i.orig \
    -p config/test/*

In place perl editing of potentially multiple files, with backups.

  perl -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : ""/eg' \
    -i.orig \
    -p config/test/*
风启觞 2024-07-18 11:17:44

对我来说,这是最简单、最强大的解决方案,您甚至可以使用相同的命令包含其他模板eval echo "$(

嵌套模板示例

  1. 创建模板文件,变量采用常规 bash 语法 ${VARIABLE_NAME}$VARIABLE_NAME

您必须在模板中使用 \ 转义特殊字符,否则它们将被 eval 解释。

template.txt

Hello ${name}!
eval echo $(<nested-template.txt)

nested-template.txt

Nice to have you here ${name} :\)
  1. 创建源文件

template.source

declare name=royman 
  1. 解析模板
source template.source && eval echo "$(<template.txt)"
  1. 输出
Hello royman!
Nice to have you here royman :)

To me this is the easiest and most powerful solution, you can even include other templates using the same command eval echo "$(<template.txt):

Example with nested template

  1. create the template files, the variables are in regular bash syntax ${VARIABLE_NAME} or $VARIABLE_NAME

you have to escape special characters with \ in your templates otherwhise they will be interpreted by eval.

template.txt

Hello ${name}!
eval echo $(<nested-template.txt)

nested-template.txt

Nice to have you here ${name} :\)
  1. create source file

template.source

declare name=royman 
  1. parse the template
source template.source && eval echo "$(<template.txt)"
  1. the output
Hello royman!
Nice to have you here royman :)

如日中天 2024-07-18 11:17:44

我创建了一个名为 shtpl 的 shell 模板脚本。 我的 shtpl 使用类似 jinja 的语法,现在我经常使用 ansible,我对此非常熟悉:

$ cat /tmp/test
{{ aux=4 }}
{{ myarray=( a b c d ) }}
{{ A_RANDOM=$RANDOM }}
$A_RANDOM
{% if $(( $A_RANDOM%2 )) == 0 %}
$A_RANDOM is even
{% else %}
$A_RANDOM is odd
{% endif %}
{% if $(( $A_RANDOM%2 )) == 0 %}
{% for n in 1 2 3 $aux %}
\$myarray[$((n-1))]: ${myarray[$((n-1))]}
/etc/passwd field #$n: $(grep $USER /etc/passwd | cut -d: -f$n)
{% endfor %}
{% else %}
{% for n in {1..4} %}
\$myarray[$((n-1))]: ${myarray[$((n-1))]}
/etc/group field #$n: $(grep ^$USER /etc/group | cut -d: -f$n)
{% endfor %}
{% endif %}


$ ./shtpl < /tmp/test
6535
6535 is odd
$myarray[0]: a
/etc/group field #1: myusername
$myarray[1]: b
/etc/group field #2: x
$myarray[2]: c
/etc/group field #3: 1001
$myarray[3]: d
/etc/group field #4: 

有关我的 github

I created a shell templating script named shtpl. My shtpl uses a jinja-like syntax which, now that I use ansible a lot, I'm pretty familiar with:

$ cat /tmp/test
{{ aux=4 }}
{{ myarray=( a b c d ) }}
{{ A_RANDOM=$RANDOM }}
$A_RANDOM
{% if $(( $A_RANDOM%2 )) == 0 %}
$A_RANDOM is even
{% else %}
$A_RANDOM is odd
{% endif %}
{% if $(( $A_RANDOM%2 )) == 0 %}
{% for n in 1 2 3 $aux %}
\$myarray[$((n-1))]: ${myarray[$((n-1))]}
/etc/passwd field #$n: $(grep $USER /etc/passwd | cut -d: -f$n)
{% endfor %}
{% else %}
{% for n in {1..4} %}
\$myarray[$((n-1))]: ${myarray[$((n-1))]}
/etc/group field #$n: $(grep ^$USER /etc/group | cut -d: -f$n)
{% endfor %}
{% endif %}


$ ./shtpl < /tmp/test
6535
6535 is odd
$myarray[0]: a
/etc/group field #1: myusername
$myarray[1]: b
/etc/group field #2: x
$myarray[2]: c
/etc/group field #3: 1001
$myarray[3]: d
/etc/group field #4: 

More info on my github

浮华 2024-07-18 11:17:44

使用 envsubst

请不要使用其他任何东西(即不要 eval

简单用法:

export name="Dana the Sane"

使用占位符创建模板 (template.txt) :

Hello ${name}

安全地替换占位符变量。 将模板提供给 envsubst 的标准输入。

envsubst < template.txt
Hello Dana the Sane

请注意,该命令 envsubst < 模板.txt> template.txt 不起作用。 重定向将在读取输出文件之前将其清零。

Use envsubst

Please don't use anything else (ie. don't eval)

Simple usage:

export name="Dana the Sane"

Create template with placeholder (template.txt):

Hello ${name}

To replace placeholder variables SAFELY. Feed the template to stdin of envsubst.

envsubst < template.txt
Hello Dana the Sane

Note, that command envsubst < template.txt > template.txt wont work. Redirection will zero the output file before reading it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文