前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux:sed修改xml中的值示例

linux:sed修改xml中的值示例

作者头像
10km
发布2021-12-17 20:44:19
3.1K0
发布2021-12-17 20:44:19
举报
文章被收录于专栏:10km的专栏10km的专栏

如下是一个简单的xml配置文件, defaultConfig.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<root description="root参数配置">
		<password description="root帐户密码">root</password>
	</root>
	<server description="Thrift服务参数配置">
		<start description="Thrift服务端是否启动">true</start>
		<port description="服务端口号">28081</port>
		<connectiontLimit description="最大连接数"></connectiontLimit>
		<idleConnectionTimeout description="空闲连接超时[秒]"></idleConnectionTimeout>
		<workerThreadCount description="工作线程数"></workerThreadCount>
	</server>
	<xhr description="XHR(XML HTTP Request)服务参数配置">
		<start description="XHR服务端是否启动">true</start>
		<port description="XHR服务端口">28082</port>
	</xhr>
	<restful description="RESTful web服务参数配置">
		<start description="RESTful 服务端是否启动">true</start>
		<port description="RESTful服务端口">8080</port>
		<swaggerEnable description="是否显示在线swagger文档">true</swaggerEnable>
		<corsEnable description="是否支持跨域访问(CORS)">true</corsEnable>
	</restful>
</configuration>

上面的xml中有server.start,xhr.start,restful.start.等三个前缀不同后缀相同的字段。 现在希望通过shell脚本修改server.start字段为false.

因为xml中有多个start字段,所以肯定不能简单的使用sed全局替换来实现。 基本的思路就是要在指定范围内进行搜索替换。 首先确定搜索范围: 通过在xml中查找server的起始标记<server>和结束标记<server>来确定搜索起始行号和结束行号 然后在搜索范围内进行正则表达式匹配替换 实现如下:

代码语言:javascript
复制
# 查找起始标志 <server 获取sed搜索范围的起始行号, = 用于打印行号
begin_line=$(sed -n '/<server/=' defaultConfig.xml )  
# begin_line 为 6
# 查找结束标志</server>获取sed搜索范围的结束行号
end_line=$(sed -n '/<\/server>/=' defaultConfig.xml)     
# end_line为 12
# 在line 6-12之间搜索招待正则表达式替换
sed -i -r "$begin_line,${end_line}s/(<start.*>).*(<\/start>)/\1false\2/1" defaultConfig.xml

封装为方便调用的函数

如果经常用到修改xml参数的情况,显然封装成一个方便调用的函数会更方便使用 如下实现了一个set_xml_value shell函数用于修改xml文件属性值,

代码语言:javascript
复制
#!/bin/bash
# 查找xml文件中指定tag的起始和结束标志
# 执行成功 tag_begin 保存起始标志行号,tag_end 保存结束标志行号
# $1 xml file
# $2 tag name
# 正常执行返回0,
# $1 不存在,$2为空返回255
# 有多个相同节点,没找到节点则失败返回255
function find_xml_tags()
{
    find_xml_tag_begin=
    find_xml_tag_end=
    if [ -f "$1" ] && [ -n "$2" ]
    then
        # 将.分割的节点名转为数组
        local array=(${2//./ })
        local size=${#array[@]}
        #echo size=$size
        if [ $size -ge 1 ]
        then
            local tag=${array[0]}            
            [ -z "$tag" ] && return 255
            # 查找第一个节点
            tag_begin=$(sed -n -r  "/<\s*$tag/=" "$1" )  && \
            tag_end=$(sed -n -r  "/<\/\s*$tag\s*>/=" "$1" )
            local ab=($tag_begin)
            local ae=($tag_end)
            # 找到标记数量不是1则失败返回
            if [ ${#ab[@]}  -ne 1 ] || [ ${#ae[@]}  -ne 1 ] ; then return 255 ; fi
            #echo $tag tag_begin=$tag_begin tag_end=$tag_end
            # 根据第一个顶级节点给定的行号范围循环查找所有其他子节点
            # 以后的每次循环都在上次找到的行号范围内查找,会一步步缩小范围
            for (( i = 1 ; i < $size ; i++ ))
            do
                tag=${array[i]}
                [ -z "$tag" ] && return 255
                # 在$tag_begin,tag_end给定范围的值内查找
                local b=$(sed -n "$tag_begin,${tag_end}p" "$1" | sed -n -r "/<\s*$tag/=")
                local e=$(sed -n "$tag_begin,${tag_end}p" "$1" | sed -n -r "/<\/\s*$tag\s*>/=")
                local ab=($b)
                local ae=($e)
                # 找到标记数量不是1则失败返回
                if [ ${#ab[@]}  -ne 1 ] || [ ${#ae[@]}  -ne 1 ] ; then return 255 ; fi
                #echo b=$b e=$e
                # b,e都是相对位置,在这里要转换为整文件的行号
                let "tag_end=$tag_begin+$e-1"
                let "tag_begin=$tag_begin+$b-1"
                #echo $tag  tag_begin=$tag_begin tag_end=$tag_end
            done
            return 0 
        fi
    fi
    return 255
}
# 设置xml文件中指定property的值
# $1 xml file
# $2 .分割的节点的字符串,如 database.jdbc
# $3 value 
# 正常执行返回0
# $1 不存在,$2为空返回255
# 有多个相同节点,没找到节点则失败返回255
# sed 修改文件失败返回sed错误代码
function set_xml_value()
{
    find_xml_tags "$1" "$2" || exit
    local last=${2##*.}
    sed -i -r "$tag_begin,${tag_end}s!(<\s*$last.*>).*(</\s*$last\s*>)!\1$3\2!1" "$1" || exit
}

调用示例

代码语言:javascript
复制
# 修改defaultConfig.xml中server.start的值为false
set_xml_value defaultConfig.xml server.start false
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-12-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 封装为方便调用的函数
  • 调用示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档