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

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

渲染脚本

  1. #!/bin/bash
  2. SRC_USER_NAME=etl
  3. SRC_USER_PWD=etl
  4. SRC_SQL="select * from tab"
  5. SRC_HOST_IP="192.168.1.1"
  6. SRC_HOST_PORT=3306
  7. SRC_DB="abc_db"
  8. TAR_USER_NAME="etl2"
  9. TAR_USER_PWD="pass2"
  10. fields_map="\"a\",\"b\",\"c\""
  11. TAR_HOST_IP="aaaadfsdfdsfjsdjf"
  12. TAR_HOST_PORT="5432"
  13. TAR_DB="tar_db"
  14. TAR_TABLENAME="tbname"
  15. eval "cat <<EOF
  16. $(< pg2pg.datax.json)
  17. EOF
  18. " > result.json

模板文档

pg2pg.datax.json

  1. {
  2. "job": {
  3. "setting": {
  4. "speed": {
  5. "byte": 1048576
  6. },
  7. "errorLimit": {
  8. "record": 0,
  9. "percentage": 0.02
  10. }
  11. },
  12. "content": [
  13. {
  14. "reader": {
  15. "name": "postgresqlreader",
  16. "parameter": {
  17. "username": "${SRC_USER_NAME}",
  18. "password": "${SRC_USER_PWD}",
  19. "where": "",
  20. "connection": [
  21. {
  22. "querySql": [
  23. "${SRC_SQL}"
  24. ],
  25. "jdbcUrl": [
  26. "jdbc:postgresql://${SRC_HOST_IP}:${SRC_HOST_PORT}/${SRC_DB}"
  27. ]
  28. }
  29. ]
  30. }
  31. },
  32. "writer": {
  33. "name": "postgresqlwriter",
  34. "parameter": {
  35. "username": "${TAR_USER_NAME}",
  36. "password": "${TAR_USER_PWD}",
  37. "column": [
  38. ${fields_map}
  39. ],
  40. "preSql": [
  41. ""
  42. ],
  43. "connection": [
  44. {
  45. "jdbcUrl": "jdbc:postgresql://${TAR_HOST_IP}:${TAR_HOST_PORT}/${TAR_DB}",
  46. "table": [
  47. "${TAR_TABLENAME}"
  48. ]
  49. }
  50. ]
  51. }
  52. }
  53. }
  54. ]
  55. }
  56. }

输出结果

  1. {
  2. "job": {
  3. "setting": {
  4. "speed": {
  5. "byte": 1048576
  6. },
  7. "errorLimit": {
  8. "record": 0,
  9. "percentage": 0.02
  10. }
  11. },
  12. "content": [
  13. {
  14. "reader": {
  15. "name": "postgresqlreader",
  16. "parameter": {
  17. "username": "etl",
  18. "password": "etl",
  19. "where": "",
  20. "connection": [
  21. {
  22. "querySql": [
  23. "select * from tab"
  24. ],
  25. "jdbcUrl": [
  26. "jdbc:postgresql://192.168.1.1:3306/abc_db"
  27. ]
  28. }
  29. ]
  30. }
  31. },
  32. "writer": {
  33. "name": "postgresqlwriter",
  34. "parameter": {
  35. "username": "etl2",
  36. "password": "pass2",
  37. "column": [
  38. "a","b","c"
  39. ],
  40. "preSql": [
  41. ""
  42. ],
  43. "connection": [
  44. {
  45. "jdbcUrl": "jdbc:postgresql://aaaadfsdfdsfjsdjf:5432/tar_db",
  46. "table": [
  47. "tbname"
  48. ]
  49. }
  50. ]
  51. }
  52. }
  53. }
  54. ]
  55. }
  56. }

核心内容是

  1. eval "cat <<EOF
  2. $(< pg2pg.datax.json)
  3. EOF
  4. " > result.json

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

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

第二, eval的用法。

语法:eval cmdLine

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

  1. [etl@data-server001 test]$ set 11 22 33 44
  2. [etl@data-server001 test]$ echo $4
  3. 44
  4. [etl@data-server001 test]$ echo $#
  5. 4
  6. [etl@data-server001 test]$ echo "\$$#"
  7. $4
  8. [etl@data-server001 test]$ eval echo "\$$#"
  9. 44

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

第三,cat <<EOF 这是一个多行输入的操作。

  1. [etl@data-server001 test]$ cat <<EOF
  2. > aaa
  3. > bbb
  4. > ccc
  5. > EOF
  6. aaa
  7. bbb
  8. ccc

EOF代表End Of File,这里表示输入结束标志,<<EOF表示定义结束符为EOF,接下来直到输入EOF时,命令结束。cat就会把内容输出。cat本来是输出文件内容的,这里把输入当做临时文件处理了。

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

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

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

  1. content=$(cat pg2pg.datax.json)
  2. eval "cat <<EOF
  3. $content
  4. EOF" > result.json
  1. eval替换$content的值

shell模板变量替换的更多相关文章

  1. 【Linux】linux bash shell之变量替换::=句法、=句法、:-句法、-句法、=?句法、?句法、:+句法、+句法

    linux bash shell之变量替换::=句法.=句法.:-句法.-句法.=?句法.?句法.:+句法.+句法   linux bash shell之变量替换::=句法.=句法.:-句法.-句法. ...

  2. shell之变量替换:临时替换

    ​${FILE:-word} 若变量为空,给变量FILE添加一个临时默认值word,FILE本身值并不变化eg: FILE1=${FILE:-word} 若FILE为空,则赋予FILE1值word $ ...

  3. shell中的条件判断、参数以及变量替换

    文章转自: http://www.cnblogs.com/maxupeng/archive/2011/07/02/2096551.html 一.test命令 test命令是shell内部命令,它计算作 ...

  4. 【Shell脚本学习9】Shell替换:Shell变量替换,命令替换,转义字符

    如果表达式中包含特殊字符,Shell 将会进行替换.例如,在双引号中使用变量就是一种替换,转义字符也是一种替换. 举个例子: #!/bin/bash a=10 echo -e "Value ...

  5. Shell变量替换,命令替换,转义字符

    如果表达式中包含特殊字符,Shell 将会进行替换.例如,在双引号中使用变量就是一种替换,转义字符也是一种替换. 举个例子: #!/bin/bash a=10 echo -e "Value ...

  6. Shell命令替换与变量替换

    命令替换 命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出.命令替换的语法: `command` 注意是反引号,不是单引号,这个键位于 Esc 键下方.下面的例子中,将命令执 ...

  7. Shell替换:Shell变量替换,命令替换,转义字符

    如果表达式中包含特殊字符,Shell 将会进行替换.例如,在双引号中使用变量就是一种替换,转义字符也是一种替换. 举个例子: 复制纯文本复制 #!/bin/bash a=10 echo -e &quo ...

  8. 《TP5.0学习笔记---模板变量输出、替换和赋值篇》

    原文地址:http://blog.csdn.net/self_realian/article/details/75214922 模板变量输出.替换和赋值 我们看一下文件编译的结果,我们知道我们现在写的 ...

  9. shell编程系列1--shell脚本中的变量替换

    shell编程系列1--shell脚本中的变量替换 变量替换总结: .${变量#匹配规则} # 从头开始匹配,最短删除 .${变量##匹配规则} # 从头开始匹配,最长删除(贪婪模式) .${变量%匹 ...

随机推荐

  1. HTTP2.0 简明笔记

    前言 RFC2616发布以来,一直是互联网发展的基石.HTTP协议也成为了可以在任何领域使用的核心协议,基于这个协议人们设计和部署了越来越多的应用.HTTP的简单本质是其快速发展的关键,但随着越来越多 ...

  2. redis进阶

    一.redis介绍 redis的功能特性 1.高速读写 2.数据类型丰富 3.支持持久化 4.多种内存分配及回收策略 5.支持事务 6.消息队列.redis用的多的还是发布-订阅模式 7.支持高可用 ...

  3. 深度学习Bible学习笔记:第二、三章 线性代数 概率与信息论

    推荐资源: <线性代数的本质>:Essence of linear algebra 视频教程 <数学之美>(科普类书籍),吴军系列书籍都不错. 易向军<大嘴巴漫谈数据挖掘 ...

  4. SPLAY,LCT学习笔记(六)

    这应该暂时是个终结篇了... 最后在这里讨论LCT的一个常用操作:维护虚子树信息 这也是一个常用操作 下面我们看一下如何来维护 以下内容转自https://blog.csdn.net/neither_ ...

  5. Crack相关

    Microsoft Office 2007专业增强版密钥:KXFDR-7PTMK-YKYHD-C8FWV-BBPVWM7YXX-XJ8YH-WY349-4HPR9-4JBYJCTKXX-M97FT-8 ...

  6. python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)

    一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...

  7. Ext.js入门:面板(五)

    一:Ext.Panel类简介 二:Ext.Panel类常用属性方法与事件 三:Ext.Panel实例运用 1.Ext.Panel类简介   类 Ext.Panel   包: Ext   定义的文件: ...

  8. 【C++ Primer | 15】构造函数与拷贝控制

    合成拷贝控制与继承 #include <iostream> using namespace std; class Base { public: Base() { cout << ...

  9. 关于trim,ltrim ,rtrim 的 移除问题

    今天在PHP中遇到一个问题: echo ltrim('D:/wamp/www/phpnow/demo/','D:/wamp/www/'); echo ltrim('D:/wamp/www/phpnow ...

  10. 如何将自己的Image镜像Push到Docker Hub

    首先需要一个docker官方账号 这里我添加了一个AspNetCore程序 通过创建了一个镜像(前面提过使用Dockerfile处理了) docker build -t dockertest . 首先 ...