转自:https://blog.youkuaiyun.com/panda_bear/article/details/8058259
最近在项目中,需要用到shell脚本来解析xml文件。在网上搜了一下,发现有xmlsh等可以用,但是都需要下载安装,使用比较麻烦,后来经过查找在stackoverflow上找到了解决方法,将脚本记录如下。
项目中的主要需求为: 在xml文件中,需要配置连接的服务器的IP和端口号等信息,供游戏逻辑程序作为服务的客户端进行解析使用。但同时,这些IP和端口号也是在进行服务器部署时需要配置的,因而这份配置在两个地方需要用到。
一开始考虑到服务器部署脚本中解析文本方便一些,因而同一份配置编写了2份。但后来考虑到后续部署的方便和较少人工配置出错的可能性,因而想到直接在部署脚本中使用xml文件来配置服务器的IP和端口号相关信息。具体脚本如下:
- #!/bin/sh
- Usage()
- {
- echo "Usage: ./install_all.sh <ranksvr_config.xml>"
- exit 1
- }
- if [ $# -ne 1 ]
- then
- Usage
- fi
- if [ ! -e "$1" ]
- then
- echo "fail to load data from file, file $1 not exist!"
- exit 1
- fi
- attrget()
- {
- ATTR_PAIR=${1#*$2=\"}
- echo "${ATTR_PAIR%%\"*}"
- }
- install_all_svrs()
- {
- if [ $# -ne 1 ]
- then
- echo "Invalid call of function install_all_svrs, no input file!"
- exit 1
- fi
- local IFS=\>
- while read -d \< ENTITY CONTENT
- do
- TAG_NAME=${ENTITY%% *}
- ATTRIBUTES=${ENTITY#* }
- if [[ $TAG_NAME == "group" ]]
- then
- GROUP=`attrget ${ATTRIBUTES} "id"`
- HOST=`attrget ${ATTRIBUTES} "host"`
- PORT=`attrget ${ATTRIBUTES} "port"`
- HTTPPORT=`attrget ${ATTRIBUTES} "httpport"`
- echo "./install.sh $GROUP $HOST $PORT $HTTPPORT"
- ./install.sh $GROUP $HOST $PORT $HTTPPORT
- fi
- done < $1
- }
- install_all_svrs $1
- #while read -d
- #do
- # var=`echo ${line} | awk '$1 ~/^[0-9]+$/ {print $1}'`
- # if [ -z ${var} ]
- # then
- # continue;
- # fi
- # ./install.sh $line
- #done < $1
其中,xml文件的解析代码主要在install_all_svrs函数中。具体原理主要还是利用shell的字符串处理技巧,下面主要分析几个主要的技巧:
${StrName%%TAG*} 表示截取字符串从左向右的第一个TAG之前的字符串;
${StrName#*TAG} 表示截取字符串从左向右的第一个TAG分割的之后的字符串,包含TAG;
${StrName%%TAG} 表示截取字符串从左向右的第一个TAG分割之前的字符串,不包含TAG;
针对具体开发中的应用:
https://github.com/feifeiyuan/features/tree/master/shell/shell%E5%A4%84%E7%90%86xml%E6%96%87%E4%BB%B6