转载

shell脚本生成xml文件

今天把这段时间学习完shell后完成工作上的一个小案件整理了一下,分享给大家!

说来也巧了,作为一个刚刚毕业半年的菜鸟,进入公司后,听公司的大牛推荐学习linux--”鸟哥的私房菜“,基本上是从去年8月份开始到了今年的1月份,基本上是把基础篇看完了,开始了解shell脚本的相关知识。刚好公司有了一个shell脚本的案件给我了,时间上也没有多紧。然后就一边学习一边开始做,虽然中途客户反映先前的业务逻辑有问题耽搁了两周,但总算是到最后完成了,自己学习的东西能用到很开心,今天闲了,把代码整理了一下,分享给大家

具体是这样:

要求是写一个shell脚本,安装要求查询数据,将符合条件的数据按照客户给定的xml样式进行组装,然后加入到crontab中,定时执行通过scp或者ftp放到客户服务器上。

具体实现步骤:

一、编写生成xml文档的代码

网上搜索了一篇博客:http://blog.csdn.net/dengzhaoqun/article/details/7262271   拿来学习了一下,感觉好用,自己就根据自己的实际情况修改了一下:

 1 #! /bin/bash  2 # filename: create_xml.sh  3 # create_wangxb_20150123  4 #  5 # 从外部传入的第一个参数作为xml的文件名  6 outfile=$1  7 # xml中的缩进位  8 tabs=0  9  10 # ++++++++++++++++++++++++++++ 11 # 组装一个节点,输出到文件 12 # 说一说传参数时的这几个区别:假如有下面这个脚本执行的命令 13 # /path/to/scriptname  opt1  opt2  opt3  opt4  14 # $0: 的值是默认是脚本的名字,从$1-$4 开始就是参数的值 15 # $# :代表后接的参数『个数』 16 # $@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);  17 # $* :代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字节,默认为空白键, 所以本例中代表『 "$1 $2 $3 $4" 』之意。 18 # 在shell中我们可以也可以使用${}包含变量名,来调用变量 19 # ++++++++++++++++++++++++++++ 20 put(){ 21     echo '<'${*}'>' >> $outfile 22 } 23  24 # 这里也是输出一个xml的节点,只是比上面的节点有更多的设置 25 # ${@:2} 的意思:它的值就是由第二个参数开始到最后一个参数,为什么要这样?有时可能你的第二个参数中有空格,shell接受参数是以空格计算的 26 put_tag() { 27     echo '<'$1'>'${@:2}'</'$1'>' >> $outfile 28 } 29 # 同样是一个输出节点函数,但是添加了CDATA,防止特殊字符造成xml解析失败 30 put_tag_cdata() { 31     echo '<'$1'><![CDATA['${@:2}']]></'$1'>' >> $outfile 32 } 33  34 put_head(){ 35     put '?'${1}'?' 36 } 37 # 这是一个缩进的算法,自行理解 38 out_tabs(){ 39     tmp=0 40     tabsstr="" 41     while [ $tmp -lt $((tabs)) ] 42     do 43         tabsstr=${tabsstr}'/t' 44         tmp=$((tmp+1)) 45     done 46     echo -e -n $tabsstr >> $outfile 47 } 48  49 tag_start(){ 50     out_tabs 51     put $1 52     tabs=$((tabs+1)) 53 } 54  55 tag() { 56     out_tabs 57     if [ "$1" == 0 ] 58     then 59         put_tag $2 $(echo ${@:3}) 60     elif [ "$1" == 1 ] 61     then 62         put_tag_cdata $2 $(echo ${@:3}) 63     fi 64 } 65  66 tag_end(){ 67     tabs=$((tabs-1)) 68     out_tabs 69     put '/'${1} 70 }

这里有一些基础知识:

关于参数:

假如有下面这个脚本执行的命令

/path/to/scriptname opt1 opt2 opt3 opt4

1 $0: 的值是默认是脚本的名字,从$1-$4 开始就是参数的值 2 $# :代表后接的参数『个数』 3 $@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);  4 $* :代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字节,默认为空白键, 所以本例中代表『 "$1 $2 $3 $4" 』之意。 5 在shell中我们可以也可以使用${}包含变量名,来调用变量

关于 ${@:2} 这种形式的说明,我转载了一篇博客:http://www.cnblogs.com/wxb0328/p/4276751.html

二、从数据库查数据利用上面的函数,制作xml文件

  1 #!/bin/bash   2 # filename: ts_xml.sh   3 # create_wangxb_20150126   4 #   5    6 PATH=/u01/app/oracle/product/10.2.0/db_1/bin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/opt/dell/srvadmin/bin:/home/p3s_batch/tools:/home/p3s_batch/bin   7 export PATH   8 # Database account information file   9 source ~/.p3src  10   11 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++  12 # set some variable   13 # XMLSCRIPT: 脚本的绝对路径  14 # MATCHING_RESULT_XML: xml_1的文件名   15 # XML_FUNC_FILE: 生成xml函数文件路径  16 # MATCHING_RESULT_QUERY_DATA: sqlplus 查出数据保存的零时文件  17 # MATCHING_RESULT_QUERY_SQL: sqlplus 查询的sql语句  18 #++++++++++++++++++++++++++++++++++++++++++++++++++++++++  19 # 下面是一些基础的设置  20 export XMLSCRIPT=/usr/p3s/batch/jaaa_match/tmp_xa_wangxb  21 XML_DIR="$XMLSCRIPT/xmldata"  22 XML_FUNC_FILE="xml_func.sh"  23   24 MATCHING_RESULT_XML="matching_result_"$(date '+%Y%m%d_%H%M%S')".xml"  25 MATCHING_RESULT_QUERY_DATA="matching_result_query_data.tmp"  26 MATCHING_RESULT_QUERY_SQL="matching_result_query.sql"  27   28 CLIENT_LIST_XML="client_list_"$(date '+%Y%m%d_%H%M%S')".xml"  29 CLIENT_LIST_QUERY_DATA="client_list_query_data.tmp"  30 CLIENT_LIST_QUERY_SQL="client_list_query.sql"  31   32 # add_wangxb_20150225  33 if [ ! -d "$XML_DIR" ];  34 then  35     mkdir $XML_DIR  36 fi  37   38 #+++++++++++++++++++++++++++  39 # modify_wangxb_20150224  40 # check for temporary file   41 #+++++++++++++++++++++++++++  42 if [ -e "$XML_DIR/$MATCHING_RESULT_XML" ];  43 then  44     rm -f $XML_DIR/$MATCHING_RESULT_XML  45 fi  46   47 if [ -e "$XMLSCRIPT/$MATCHING_RESULT_QUERY_DATA" ];  48 then  49     MATCHING_RESULT_QUERY_DATA="matching_result_query_data_"$(date '+%Y%m%d%H%M%S')".tmp"  50 fi  51 #+++++++++++++++++++++++++++++++++++++++++++++++++  52 # add_wangxb_20150225  53 # check system time,  choice query time period  54 # 这是是根据crontab每天执行的时间,取得我们查询数据库时的where条件的时间区间  55 #+++++++++++++++++++++++++++++++++++++++++++++++++  56 sys_datetime=$(date '+%Y%m%d%H')  57 first_chk_datetime="$(date '+%Y%m%d')04"  58 second_chk_datetime="$(date '+%Y%m%d')12"  59 third_chk_datetime="$(date '+%Y%m%d')20"  60 # 由于服务器crontab是上面的时间,但是执行的shell比较多,在调用我这个shell的时候,不一定就是04:3012:30, 20:30所以,这里的根据系统的时间判断时 范围给的比较宽  61 case $sys_datetime in  62     "$first_chk_datetime"|"$(date '+%Y%m%d')05"|"$(date '+%Y%m%d')06"|"$(date '+%Y%m%d')07")  63         chk_start=$(date '+%Y-%m-%d 21:00:00' -d '-1 day')  64         chk_end=$(date '+%Y-%m-%d 04:29:59')  65     ;;  66     "$second_chk_datetime"|"$(date '+%Y%m%d')13"|"$(date '+%Y%m%d')14"|"$(date '+%Y%m%d')15")  67         chk_start=$(date '+%Y-%m-%d 04:30:00')  68         chk_end=$(date '+%Y-%m-%d 12:29:59')  69   70     ;;  71     "$third_chk_datetime"|"$(date '+%Y%m%d')21"|"$(date '+%Y%m%d')22"|"$(date '+%Y%m%d')23")  72         chk_start=$(date '+%Y-%m-%d 12:30:00')  73         chk_end=$(date '+%Y-%m-%d 20:59:59')  74   75     ;;  76     *)  77         chk_start=$(date '+%Y-%m-%d 00:00:00')  78         chk_end=$(date '+%Y-%m-%d 23:59:59')  79   80     ;;  81 esac  82   83 # modify_wangxb_20150310  84 # 下面的是做一个oracle数据库连接的测试,如果连接失败,后续代码不再执行,并且写入错误日志  85 $ORACLE_HOME/bin/sqlplus -s $ORAUSER_WEB_PASDB << EOF  86 set echo off  87 set feedback off  88 alter session set nls_date_format='YYYY-MM-DD:HH24:MI:SS';  89 select sysdate from dual;  90 quit  91 EOF  92 if [ $? -ne 0 ]  93 then   94     echo "********** DBへのリンク己窃した **********"  95     exit  96 else  97     echo "********** DBへのリンクOKです **********"  98 fi  99 # sqlplus就是oracle的一个客户端软件,具体使用方法可以问度娘,这里传入要执行的sql和参数,将结果 > 输出到指定文件 100 $ORACLE_HOME/bin/sqlplus -s $ORAUSER_WEB_PASDB @$XMLSCRIPT/$MATCHING_RESULT_QUERY_SQL "$chk_start" "$chk_end" > $XMLSCRIPT/$MATCHING_RESULT_QUERY_DATA 101  102  103 # create matching result's xml file 104 # add_wangxb_20150227 105 # 下面的算法就是将查出的数据进行分析,调用xml函数生成xml文件 106 source "$XMLSCRIPT/$XML_FUNC_FILE" "$XML_DIR/$MATCHING_RESULT_XML" 107 put_head 'xml version="1.0" encoding="utf-8"' 108 tag_start 'ROOT' 109 if [ -s "$XMLSCRIPT/$MATCHING_RESULT_QUERY_DATA" ]; 110 then 111     datas=${XMLSCRIPT}/${MATCHING_RESULT_QUERY_DATA} 112     #for res in $datas 113     while read res; 114     do 115         stock_id=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $1}') 116         seirino=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $2}') 117         match_flg=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $3}') 118         unmatch_riyuu=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $4}') 119         up_date_tmp=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $5}') 120         up_date=$(echo $up_date_tmp | awk 'BEGIN {FS="@"} {print $1 " " $2}') 121         tag_start 'MATCHING' 122         tag 0 'STOCKID' ${stock_id:-""} 123         tag 0 'SEIRINO' ${seirino:-""} 124         tag 0 'RESULT' ${match_flg:-""} 125         tag 1 'REASON' ${unmatch_riyuu:-""} 126         tag 0 'UPDATE_DATE' ${up_date:-""} 127         tag_end 'MATCHING' 128     done < $datas 129 fi 130 tag_end 'ROOT' 131 rm $XMLSCRIPT/$MATCHING_RESULT_QUERY_DATA 132  133  134 # create client list's xml file 135 # add_wangxb_2015027 136 # 下面的是再生成一个xml文件,和上面一样 137 if [ -e "$XML_DIR/$CLIENT_LIST_XML" ]; 138 then 139     rm -f $XML_DIR/$CLIENT_LIST_XML 140 fi 141  142 if [ -e "$XMLSCRIPT/$CLIENT_LIST_QUERY_DATA" ]; 143 then 144     CLIENT_LIST_QUERY_DATA="client_list_query_data_"$(date '+%Y%m%d%H%M%S')".tmp" 145 fi 146  147  148 $ORACLE_HOME/bin/sqlplus -s $ORAUSER_MND @$XMLSCRIPT/$CLIENT_LIST_QUERY_SQL > $XMLSCRIPT/$CLIENT_LIST_QUERY_DATA 149  150 source "$XMLSCRIPT/$XML_FUNC_FILE" "$XML_DIR/$CLIENT_LIST_XML" 151 put_head 'xml version="1.0" encoding="utf-8"' 152 tag_start 'ROOT' 153 if [ -s "$XMLSCRIPT/$CLIENT_LIST_QUERY_DATA" ]; 154 then 155     datas=${XMLSCRIPT}/${CLIENT_LIST_QUERY_DATA} 156     #for res in $datas 157     while read res; 158     do 159         corporation_id=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $1}') 160         corporation_name=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $2}') 161         client_id=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $3}') 162         client_print_name=$(echo $res | awk 'BEGIN {FS="//^//*//^"} {print $4}') 163         tag_start 'CLIENT' 164         tag 0 'CORPORATION_ID' ${corporation_id:-""} 165         tag 1 'CORPORATION_NAME' ${corporation_name:-""} 166         tag 0 'CLIENT_ID' ${client_id:-""} 167         tag 1 'CLIENT_PRINT_NAME' ${client_print_name:-""} 168         tag_end 'CLIENT' 169     done < $datas 170 fi 171 tag_end 'ROOT' 172 rm $XMLSCRIPT/$CLIENT_LIST_QUERY_DATA 173  174  175 # add_wangxb_20150304 176 # Convert xml file encoding 177 # 这是将xml文件进行转码,命令是iconv 178 if [ -e "$XML_DIR/$MATCHING_RESULT_XML" ]; 179 then 180     echo "********** matching_result.xmlファイルコ〖ドを啪垂し、**********" 181     iconv -f euc-jp -t utf-8 $XML_DIR/$MATCHING_RESULT_XML  -o $XML_DIR/$MATCHING_RESULT_XML.utf-8 182     mv $XML_DIR/$MATCHING_RESULT_XML.utf-8 $XML_DIR/$MATCHING_RESULT_XML 183 fi 184 if [ -e "$XML_DIR/$CLIENT_LIST_XML" ]; 185 then 186     echo "********** client_list.xmlフィルコ〖ドを啪垂し、**********" 187     iconv -f euc-jp -t utf-8 $XML_DIR/$CLIENT_LIST_XML  -o $XML_DIR/$CLIENT_LIST_XML.utf-8 188     mv $XML_DIR/$CLIENT_LIST_XML.utf-8 $XML_DIR/$CLIENT_LIST_XML 189 fi 190  191 # add_wangxb_20150304 192 # Send the xml file to the destination server by ftp 193 #ftp_host="222.***.***.***" 194 #USER="***" 195 #PASS="***" 196 #ftp -i -n $ftp_host << EOF 197 #user $USER $PASS 198 #cd / 199 #lcd $XML_DIR/ 200 #put $MATCHING_RESULT_XML 201 #put $CLIENT_LIST_XML 202 #quit 203 #EOF 204  205 # test ftp 206 # 通过ftp将xml文件放到客户服务器上,ftp_host:客户服务器地址,user登录名,pass密码 207 ftp_host="***.***.***.***" 208 USER="***" 209 PASS="***" 210 dir="/upload" 211 ftp -i -n $ftp_host << EOF 212 user $USER $PASS 213 cd /upload/ 214 lcd $XML_DIR/ 215 put $MATCHING_RESULT_XML 216 put $CLIENT_LIST_XML 217 quit 218 EOF 219  220  221 # Save the program log file 222 YYMM=$(date +'%Y%m%d%H%M') 223 cp /tmp/create_xml.log /usr/p3s/batch/jaaa_match/tmp_xa_wangxb/logs/create_xml.log.$YYMM 224  225 # Send error log files into the Admin mailbox 226 info_to_mail_1="**@**.co.jp" 227 info_to_mail_2="***@**.co.jp" 228 # nkf 日文转码的一个命令 229 title=$(echo "test" | nkf -j) 230 nkf -j < /tmp/create_xml.log | mail -s $title $info_to_mail_1 $info_to_mail_2 231  232  233 #exit

关于nkf 日文转码 :http://www.cnblogs.com/wxb0328/p/4333820.html

本来是用scp传送的, 但是后面修改了,这里把自己为scp传送找到的一个,不用密码可立即登入的 ssh 用户

在鸟哥私房菜的服务器架设篇的第十一章中有介绍:http://vbird.dic.ksu.edu.tw/linux_server/0310telnetssh_2.php#ssh_nopasswd

下面是执行的两个sql文件

 1 SET PAGESIZE 0  2 SET FEEDBACK OFF  3 SET VERIFY OFF  4 SET ECHO OFF  5 SET HEADING OFF  6 SET TIMI OFF  7 SET LINESIZE 1000  8 SET WRAP OFF  9  10  11 SELECT s.STOCKID|| '^*^' ||a.SERI_NO|| '^*^' ||a.MATCH_FLG|| '^*^' ||a.UNMATCH_RIYUU|| '^*^' ||to_char(a.UP_DATE,'YYYY-MM-DD@HH24:MI:SS') UP_DATE FROM aaa_stock_db a LEFT JOIN SENDDATAAPPRAISALPROTO s ON a.SERI_NO=s.SEIRINO WHERE a.UP_DATE BETWEEN to_date('&1','yyyy-mm-dd hh24:mi:ss') AND to_date('&2','yyyy-mm-dd hh24:mi:ss') AND a.DEL_FLG=0 ORDER BY a.UP_DATE DESC; 12  13 exit
 1 SET PAGESIZE 0  2 SET FEEDBACK OFF  3 SET VERIFY OFF  4 SET ECHO OFF  5 SET HEADING OFF  6 SET TIMI OFF  7 SET LINESIZE 1000  8 SET WRAP OFF  9  10  11 SELECT a.CORPORATION_ID|| '^*^' ||a.CORPORATION_NAME|| '^*^' ||b.CLIENT_ID|| '^*^' ||(select CLIENT_PRINT_NAME from CLIENT_MASTER where CLIENT_ID = b.CLIENT_ID) as CLIENT_PRINT_NAME FROM M_CORPORATION_MASTER a LEFT JOIN M_CORPORATION_GROUP b ON (a.CORPORATION_ID = b.CORPORATION_ID) WHERE a.DEL_FLG=0 AND b.DEL_FLG=0; 12  13 exit

三、来看看效果

当然中间出现了许多bug,不过慢慢修改吗,兵来将挡,水来土掩,bug来了自己调么

shell脚本生成xml文件

就这样简单的整理一下,可能光这么写不够完整,但是,中间设计的知识也很多,不能展开了说,做个分享,大家有用到的时候也是个思路,具体的某些知识点可以用到了再去找资料了

题外话:

这几天打算辞职,想去外面,但是听了在外面找工作的同学说,外面要求的技术很多:“什么优化,缓存,环境搭建啊,高并发,读写分离,负载均衡等等”  。突然就没有了去外面的激情,而且毕竟才毕业半年,工资也不高,毕业前出去旅行也借了5K的钱都没有还,哎、、、本来想着去深圳,怎么也能找个6K+的工作,现在听听,觉得能力不够啊,这是这些能力也不是一天两天能掌握的,很郁闷,如果不出去,要等到什么时候,趁年轻不出去怕以后就没有机会!

哎、、、这个决定该怎么做,有点烦!如果哪位大牛能够看到小弟这篇博客,希望能提点建设性的意见,不胜感激!!涕泗横流!!!

正文到此结束
Loading...