linux xml 格式化输出,案例十五、格式化输出xml文件

在工作中我们多多少少都接触过xml文件,它的格式非常有规律性,但读起来因为有太多的标签(<>),不能一目了然,就比如下面一段配置:

zzz

aaa

xxx

yyy

本案例的需求是从上面的XML文本中提取groupId和artifactld,并输出为如下格式:artifactItem:groupId:zzz

artifactItem:artifactld:aaa

artifactItem:groupId:xxx

artifactItem:artifactld:yyy

知识点一:关于XML的小常识

XML(Extensible Markup Language),中文叫做:可扩展标记语言。XML和HTML很像,都是一种标记语言。XML主要用来传送以及携带数据信息,而不是用来展示的,所以读起来就有点障碍。

有不少服务的配置文件就是一个XML文本,在XML文本中定义对应的配置,就比如本案例中示例文本就是一个配置文件。XML的作用主要在于存储数据,它以纯文本格式进行存储,因此提供了一种独立于软件和硬件的数据存储方法。这让创建不同的应用程序可以共享的数据变得更加容易。由于XML文本的格式是固定的,无论是Windows、Linux或者MAC等其他操作系统,都可以识别,所以它的兼容性很好。

有一点,我们必须要知道,就是XML是一种不作为的标记语言,即,它不像HTML需要被解析、执行然后展示漂亮的网页,它存在的意义仅仅是结构化、存储以及传输信息。

知识点二:截取文档中两个关键词中间的行

需求是,把文本中包含abc和123中间的部分打印出来,假设abc在123上面。如果使用sed,一条命令即可实现:# sed -n '/abc/,/123/p' 1.txt

不过这样依然有abc和123的行,要想去掉他们,也很简单:# sed -n '/abc/,/123/p' 1.txt |sed '/abc/d;/123/d'

如果文本中有多个abc和123,则会同时把所有符合条件的行全部打印出来,下面提供一个比较笨的土方法,帮助练习逻辑思维能力。

mysed.sh#!/bin/bash

#先获取abc和123所在行的行号

egrep -n 'abc|123' 1.txt |awk -F ':' '{print $1}' > /tmp/line_number.txt

#计算一共有多少包含abc和123的行

n=`wc -l /tmp/line_number.txt|awk '{print $1}'`

#计算一共有多少对abc和123

n2=$[$n/2]

for i in `seq 1 $n2`

do

#每次循环都要处理两行,第一次是1,2,第二次是3,4,依此类推

m1=$[$i*2-1]

m2=$[$i*2]

#每次遍历都要获取abc和123的行号

nu1=`sed -n "$m1"p /tmp/line_number.txt`

nu2=`sed -n "$m2"p /tmp/line_number.txt`

#获取abc下面一行的行号

nu3=$[$nu1+1]

#获取123上面一行的行号

nu4=$[$nu2-1]

#用sed把abc和123中间的行打印出来

sed -n "$nu3,$nu4"p 1.txt

#便于分辨,添加分隔行符号

echo "============="

done

提供一个测试的文本1.txt,内容如下:alskdfkjlasldkjfabalskdjflkajsd

asldkfjjk232k3jlk2

alskk2lklkkabclaksdj

skjjfk23kjalf09wlkjlah lkaswlekjl9

aksjdf

123asd232323

aaaaaaaaaa

222222222222222222

abcabc12121212

fa2klj

slkj32k3j

22233232123

bbbbbbb

ddddddddddd

用sed处理,结果是:# sed -n '/abc/,/123/p' 1.txt |sed '/abc/d;/123/d'

skjjfk23kjalf09wlkjlah lkaswlekjl9

aksjdf

fa2klj

slkj32k3j

用mysed.sh处理,结果是:# sh mysed.sh

skjjfk23kjalf09wlkjlah lkaswlekjl9

aksjdf

=============

fa2klj

slkj32k3j

=============

案例分析

1)首先要找到和中间的数据段,针对这部分数据进行分析

2)可以找到XML文档中包含和的行的行号,然后使用sed把这部分内容截取出来

3)处理截取出来的数据段,使用sed、awk截取关键词以及对应的值

本案例参考脚本#!/bin/bash

#按要求输出XML内容,本脚本定制性较强,不可通用

#作者:

#日期:

#假设要处理的XML文档名字为test.xml

#获取和所在的行号

grep -n 'artifactItem>' test.xml |awk '{print $1}' |sed 's/://' > /tmp/line_number.txt

#计算和的行一共有多少行

n=`wc -l /tmp/line_number.txt|awk '{print $1}'`

#定义获取关键词和其值的函数

get_value(){

#$1和$2为函数的两个参数,即下一行和上一行的行号(这个操作在下面)

#截取出和中间的内容,然后获取关键词(如groupId)和其对应的值,写入/tmp/value.txt

sed -n "$1,$2"p test.xml|awk -F '' '{print $1,$2}' > /tmp/value.txt

#遍历整个/tmp/value.txt文档

cat /tmp/value.txt|while read line

do

#x为关键词,如groupId

#y为关键词的值

x=`echo $line|awk '{print $1}'`

y=`echo $line|awk '{print $2}'`

echo artifactItem:$x:$y

done

}

#由于/tmp/line_number.txt是成对出现的,n2为一共多少对

n2=$[$n/2]

#针对每一对,打印关键词和对应的值

for j in `seq 1 $n2`

do

#每次循环都要处理两行,第一次是1,2,第二次是3,4,依此类推

m1=$[$j*2-1]

m2=$[$j*2]

#每次遍历都要获取和的行号

nu1=`sed -n "$m1"p /tmp/line_number.txt`

nu2=`sed -n "$m2"p /tmp/line_number.txt`

#获取下面一行的行号

nu3=$[$nu1+1]

#获取上面一行的行号

nu4=$[$nu2-1]

get_value $nu3 $nu4

done

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值