JAVA替换shell模板内容_shell模板变量替换

我们经常使用一些模板语言来处理一些变量替换。比如jsp,php,velocity,freemarker,thymeleaf等。那对于shell来说,应该怎样替换变量呢。有一种很简单的办法可以做到。

先来看一个应用场景。在datax是阿里开源的一个异构数据源同步框架,其配置文档是json的,我想要用shell去调用执行pg到pg的数据同步,需要根据我的配置生成对应的配置文件。这如果用java来做就是维护一个对象,设置value,最后json-encode就好了。要是使用shell,这样也可以做到:

渲染脚本

#!/bin/bash

SRC_USER_NAME=etl

SRC_USER_PWD=etl

SRC_SQL="select * from tab"

SRC_HOST_IP="192.168.1.1"

SRC_HOST_PORT=3306

SRC_DB="abc_db"

TAR_USER_NAME="etl2"

TAR_USER_PWD="pass2"

fields_map="\"a\",\"b\",\"c\""

TAR_HOST_IP="aaaadfsdfdsfjsdjf"

TAR_HOST_PORT="5432"

TAR_DB="tar_db"

TAR_TABLENAME="tbname"

eval "cat <

$(< pg2pg.datax.json)

EOF

" > result.json

模板文档

pg2pg.datax.json

{

"job": {

"setting": {

"speed": {

"byte": 1048576

},

"errorLimit": {

"record": 0,

"percentage": 0.02

}

},

"content": [

{

"reader": {

"name": "postgresqlreader",

"parameter": {

"username": "${SRC_USER_NAME}",

"password": "${SRC_USER_PWD}",

"where": "",

"connection": [

{

"querySql": [

"${SRC_SQL}"

],

"jdbcUrl": [

"jdbc:postgresql://${SRC_HOST_IP}:${SRC_HOST_PORT}/${SRC_DB}"

]

}

]

}

},

"writer": {

"name": "postgresqlwriter",

"parameter": {

"username": "${TAR_USER_NAME}",

"password": "${TAR_USER_PWD}",

"column": [

${fields_map}

],

"preSql": [

""

],

"connection": [

{

"jdbcUrl": "jdbc:postgresql://${TAR_HOST_IP}:${TAR_HOST_PORT}/${TAR_DB}",

"table": [

"${TAR_TABLENAME}"

]

}

]

}

}

}

]

}

}

输出结果

{

"job": {

"setting": {

"speed": {

"byte": 1048576

},

"errorLimit": {

"record": 0,

"percentage": 0.02

}

},

"content": [

{

"reader": {

"name": "postgresqlreader",

"parameter": {

"username": "etl",

"password": "etl",

"where": "",

"connection": [

{

"querySql": [

"select * from tab"

],

"jdbcUrl": [

"jdbc:postgresql://192.168.1.1:3306/abc_db"

]

}

]

}

},

"writer": {

"name": "postgresqlwriter",

"parameter": {

"username": "etl2",

"password": "pass2",

"column": [

"a","b","c"

],

"preSql": [

""

],

"connection": [

{

"jdbcUrl": "jdbc:postgresql://aaaadfsdfdsfjsdjf:5432/tar_db",

"table": [

"tbname"

]

}

]

}

}

}

]

}

}

核心内容是

eval "cat <

$(< pg2pg.datax.json)

EOF

" > result.json

其中有几个语法需要学习下。

第一shell中变量的定义,变量赋值时,等号(=)`两边必须没有空格。

第二, eval的用法。

语法:eval cmdLine

eval会对后面的cmdLine进行两遍扫描,如果第一遍扫描替换变量,然后执行cmdLine.

[etl@data-server001 test]$ set 11 22 33 44

[etl@data-server001 test]$ echo $4

44

[etl@data-server001 test]$ echo $#

4

[etl@data-server001 test]$ echo "\$$#"

$4

[etl@data-server001 test]$ eval echo "\$$#"

44

本组测试中,echo可以读取变量的第一层定义,所以$#代表参数个数4,$4代表第4个参数44。但我们想要直接取最后一个参数,需要使用变量的值作为变量的value。eval就会再次扫描一遍。

第三,cat <

[etl@data-server001 test]$ cat <

> aaa

> bbb

> ccc

> EOF

aaa

bbb

ccc

EOF代表End Of File,这里表示输入结束标志,<

第四, $(xxx) 表示执行命令,和两个反引号的效果相同,会执行里面的命令。所以< pg2pg.datax.json 才会读取文件内容。

最后输入EOF结束内容。需要注意EOF前后不要有空格,必须是回车,不然就不代表最后一个字符了。

为了更加容易理解,可以修改渲染脚本

content=$(cat pg2pg.datax.json)

eval "cat <

$content

EOF" > result.json

eval替换$content的值

你可能感兴趣的:(JAVA替换shell模板内容)