我想运行这个用法的shell脚本:
./run A.txt B.xml
A.txt包含一些统计信息:
Accesses = 1
Hits = 2
Misses = 3
Evictions = 4
Retries = 5
B.xml看起来像:
<stat name="total_accesses" value="0"/>
<stat name="total_misses" value="0"/>
<stat name="conflicts" value="0"/>
我想从A.txt替换B.xml中的一些统计信息。例如,我想
1- find "Accesses" in A.txt
2- find "total_accesses" in B.xml
3- replace 0 with 1
1- find "Misses" in A.txt
2- find "total_misses" in B.xml
3- replace 0 with 3
所以B.xml看起来像是:
<stat name="total_accesses" value="1"/>
<stat name="total_misses" value="3"/>
<stat name="conflicts" value="0"/>
我想用shell“sed”命令做到这一点。但是我发现它很复杂,因为正则表达式很难理解。
“sed”能帮助我解决这个问题,还是我必须找到另一种方法?
答案 0 :(得分:1)
这是一个执行您想要的shell脚本:
#!/bin/bash
while read line
do
key=`echo $line | cut -d' ' -f1`
value=`echo $line | cut -d' ' -f3`
xmlLine=`grep -i $key $2`
if [ -n "$xmlLine" ]; then
for num in `seq 5`
do
field[${num}]=`echo "$xmlLine" | cut -d'"' -f${num}`
done
echo ${field[1]}\"${field[2]}\"${field[3]}\"$value\"${field[5]}
fi
done
You can copy it to a file say A.sh
, give run permissions to it (chmod +x A.sh
) and then:
A.sh
请注意,此代码不适合生产,正则表达式对这些脚本至关重要。
答案 1 :(得分:1)
虽然你可以在命令行上破解它,但我建议你不要这样做。
XML太脆弱而无法以这种方式处理 - 使用适当的XML库并在操作之前解析XML。否则你很容易就会破坏XML。例如用Ruby,Python或Perl编写脚本并使用XML库。
答案 2 :(得分:1)
对于这样一个简单的案例,这可能有点重,但这里有一个Python脚本可以完成这项工作:
#!/usr/bin/env python
import sys
import xml.etree.ElementTree as etree
# read A.txt; fill stats
stats = {}
for line in open(sys.argv[1]):
if line.strip():
name, _, count = line.partition('=')
stats["total_"+name.lower().strip()] = count.strip()
# read B.xml; fix to make it a valid xml; replace stat[@value]
root = etree.fromstring("<root>%s</root>" % open(sys.argv[2]).read())
for s in root:
if s.get('name') in stats:
s.set('value', stats[s.get('name')])
print etree.tostring(s),
$ python fill-xml-template.py A.txt B.xml
<stat name="total_accesses" value="1" />
<stat name="total_misses" value="3" />
<stat name="conflicts" value="0" />
要逐步处理输入文件或进行更改,您可以使用以下内容:
#!/usr/bin/env python
import fileinput
import sys
import xml.etree.ElementTree as etree
try: sys.argv.remove('-i')
except ValueError:
inplace = False
else: inplace = True # make changes inplace if `-i` option is specified
# read A.txt; fill stats
stats = {}
for line in open(sys.argv.pop(1)):
if line.strip():
name, _, count = line.partition('=')
stats["total_"+name.lower().strip()] = count.strip()
# read input; replace stat[@value]
for line in fileinput.input(inplace=inplace):
s = etree.fromstring(line)
if s.get('name') in stats:
s.set('value', stats[s.get('name')])
print etree.tostring(s)
$ python fill-xml-template.py A.txt B.xml -i
它可以从stdin读取或处理多个文件:
$ cat B.xml | python fill-xml-template.py A.txt
<stat name="total_accesses" value="1" />
<stat name="total_misses" value="3" />
<stat name="conflicts" value="0" />