我有一个XML文件包含若干图片中重复的代码段,我想将标记中的值提取出来排列成一定的格式,比如下面这种(以tab分隔):
#host oidgroup comm desc
192.168.1.1 CpuUtilization_MF public 192.168.1.1_CPUUtilizaton
192.168.1.2 CpuUtilization_MF public 192.168.1.2_CPUUtilizaton
192.168.1.3 CpuUtilization_MF public 192.168.1.3_CPUUtilizaton
192.168.1.4 CpuUtilization_MF public 192.168.1.4_CPUUtilizaton
192.168.1.5 CpuUtilization_MF public 192.168.1.5_CPUUtilizaton
能看见图片了么?
首先谢谢你的解答,非常感谢您!
不过我有几个地方不太明白,问题如下:
1.FILE=(`ls -l $filename >/dev/null 2>&1 | awk '{print $8}'`) 这段是想实现什么呢?我去掉不影响输出结果。
2.for语句中的i<${#HOST[@]}是什么意思?
3.当某行记录中存在空格的时候,数组提取会出错,比如第100行内容为ICMP 192.168.1.1,那么我利用${DESC[99]}结果却为ICMP,这是为什么呢?
希望你能帮我解答,谢谢!
1.FILE=(`ls -l $filename >/dev/null 2>&1 | awk '{print $8}'`) 这段是想实现什么呢?我去掉不影响输出结果。
##############################################
FILE=(`ls -l $filename >/dev/null 2>&1 | awk '{print $8}'`)
#这个是另一种判断文件是否存在的方式,跟下边那个功能一样。
if [ ! -z $FILE ];then
echo -e "host\t\toidgroupname\t\tcomm\t\tdesc" >$filename
fi
###############################################
上边这段可以全删掉,只留下边这段就可以了
if [ -f $filename ];then
echo -e "host\t\toidgroupname\t\tcomm\t\tdesc" >$filename
fi
#主要功能是判断追加数据的文件是否存在,不存在的话就重新创建一个,存在的话就继续追加。
2.for语句中的i<${#HOST[@]}是什么意思?
HOST这个数组中元素的个数
3.光听你用文字描述,我很难理解你所描述的情况,比如记录中存在空格,空格在记录中的什么位置,第100行ICMP这段是什么样的?。我只是按照图片里的格式写的。这个具体情况,还得具体分析。毕竟我不知道你xml整体是什么样的。
比如
ICMP 192.168.1.1
ICMP 192.168.1.2
ICMP 192.168.1.3
ICMP 192.168.1.4
ICMP 192.168.1.5
这样子中间有空格,提取出来得出如下的结果:
${DESC[0]}等于ICMP
${DESC[1]}等于192.168.1.1
希望每行存成一个数组元素(每行当中都可能有空格)
你是不是想要这样的效果?
$./test.sh file
$cat record.txt
$./test.sh file
(=^.^=) 日 1月 08 13:29:44
$cat record.txt
host oidgroupname comm desc
192.168.1.1 CpuUtilization_MF public 192.168.1.1_CPUUtilization
192.168.1.2 CpuUtilization_MF public 192.168.1.2_CPUUtilization
192.168.1.3 CpuUtilization_MF public 192.168.1.3_CPUUtilization
192.168.1.4 CpuUtilization_MF public ICMP 192.168.1.4
192.168.1.5 CpuUtilization_MF public ICMP 192.168.1.5
我实在不知道多数组,其中一个数组元素包含空格的写法。试了很多方式都不行。
所以我能想到的只有先把数据整理出来,然后以行的形式读取。如果谁有更好的方法
我很愿意学习一下。没办法能力有限,目前我能想到的只有这种方法了。不过
我觉得如果用awk写应该会比较简单些,但是我awk还不太会。= =!!!
#!/bin/bash
if [ -z $1 ];then
echo 'USAGE:COMMAND FILENAME'
exit 0
fi
filename=record.txt
sed -n 's/.*>\(.*\)/\1/p' $1 >host.tmp
sed -n 's/.*>\(.*\)/\1/p' $1 >oidg.tmp
sed -n 's/.*>\(.*\)/\1/p' $1 >comm.tmp
sed -n 's/.*>\(.*\)/\1/p' $1 >desc.tmp
if [ ! -f $filename ];then
echo -e "host\t\toidgroupname\t\tcomm\t\tdesc" >$filename
fi
while read -u1 host && read -u2 oidg && read -u3 comm && read -u4 desc;do
echo -e "${host}\t${oidg}\t${comm}\t\t${desc}" >>$filename
done 1<host.tmp 2<oidg.tmp 3<comm.tmp 4<desc.tmp
rm -rf host.tmp oidg.tmp comm.tmp desc.tmp