这个脚本还只是测试用的,完全没有考虑效率等问题,只是能实现功能而已。
需求:
把68.xml文件中的号码信息处理成两行,每行一个号码信息
源文件 68.xml:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <Result xmlns="http://schemas.ericsson.com/pg/hlr/13.5/"> <Request> <command>HEMSCMP:MSISDNALL</command> <starttime>2012-10-16 15:10:10</starttime> <jobid>68</jobid> </Request> <CAMELSubscriptionData> <CAMELSubscription> <msisdn>8613*****8561</msisdn> <CamelTriggeringDetectionPointData> <tdptype>OCTDP</tdptype> <tdp>2</tdp> <sk>91</sk> <gsa>8613749296</gsa> <deh>0</deh> <cch>2</cch> </CamelTriggeringDetectionPointData> <CamelTriggeringDetectionPointData> <tdptype>TCTDP</tdptype> <tdp>12</tdp> <sk>91</sk> <gsa>8613749296</gsa> <deh>0</deh> <i>false</i> <cch>2</cch> </CamelTriggeringDetectionPointData> </CAMELSubscription> <CAMELSubscription> <msisdn>8613*****8560</msisdn> <CamelTriggeringDetectionPointData> <tdptype>OCTDP</tdptype> <tdp>2</tdp> <sk>91</sk> <gsa>8613749296</gsa> <deh>0</deh> <cch>2</cch> </CamelTriggeringDetectionPointData> <CamelTriggeringDetectionPointData> <tdptype>TCTDP</tdptype> <tdp>12</tdp> <sk>91</sk> <gsa>8613749296</gsa> <deh>0</deh> <i>false</i> <cch>2</cch> </CamelTriggeringDetectionPointData> </CAMELSubscription> </CAMELSubscriptionData> </Result>
处理脚本 for.sh:
#!/bin/bash #把源文件68.xml中用<>关键字</>标注出来的行改成<>+空格+关键字+空格+</> cat 68.xml | sed 's/>/> /' |sed 's/<\// <\//' if [ -f re.txt ]; then rm re.txt #re.txt用来保存最终处理结果 rm re.txt.int #re.txt.init用来保存中间结果 else echo "re.txt not exist" fi #因为需求要根据号码来处理数据,所以把号码所在的行号保存到文本中,以此作为循环的依据 sed -n "/<msisdn>/=" 68.xml >number.txt #把每个号码所在的行号读取到数组array1中 array1=($(awk '{print $1}' number.txt)) #循环,开始遍历68.xml for((i=0;i<${#array1[@]};i++)) do #每遍历一个号码都清空re.txt.ini cat /dev/null > re.txt.ini #注意:在sed中可以使用参数 msisdn1=`sed -n "${array1[i]}p" 68.xml |awk '{print $2}'` echo $msisdn1 >>re.txt.ini #确定子循环的起点、终点 let "beginnum=${array1[i]}+2" let "endnum=${array1[i]}+16" #把起点和终点间的行,用sed ,awk保存到数组array2中 array2=($(sed -n "${beginnum}","${endnum}p" 68.xml |awk '{print $2}')) for ((j=0;j<${#array2[@]};j++)) do echo ${array2[j]} >>re.txt.ini done #现在保存到re.txt.init中的数据是按列存放的,需要改成按行存放 #sed 's/OCTDP//' ,是用空格替换字符OCTDP,注意这里一定要用printf,要是用print,结果会出现: #%s %s 2 %s 91 %s 8613749296 %s 0 %s 2 %s %s 12 %s 91 %s 8613749296 %s 0 %s false %s 2 echo -e `awk '{printf "%s ",$1}' re.txt.ini |sed 's/OCTDP//' |sed 's/TCTDP//'` >> re.txt done