使用bash脚本在XML文件中查找选项块
我有一个结构如下的XML文件:使用bash脚本在XML文件中查找选项块,xml,linux,bash,shell,sh,Xml,Linux,Bash,Shell,Sh,我有一个结构如下的XML文件: <?xml version="1.0" encoding="utf-8"?> <questions> <property name="q154"> <q154> <Property name="intro" value="Based on the information, {
<?xml version="1.0" encoding="utf-8"?>
<questions>
<property name="q154">
<q154>
<Property name="intro" value="Based on the information, {{1}} is older than {{2}}"/>
<Property name="op1">
<Pstructure>
<Property name="choices">
<Value>Mary</Value>
<Value>John</Value>
<Value>Carl</Value>
</Property>
<Property name="correct-indices">
<Value>3</Value>
</Property>
<Property name="hints">
<Value>Some hint here</Value>
<Value>blah blach blah</Value>
</Property>
</Pstructure>
</Property>
<Property name="op2">
<Pstructure>
<Property name="choices">
<Value>Albert</Value>
<Value>Nicole</Value>
<Value>Lizeth</Value>
</Property>
<Property name="correct-indices">
<Value>1</Value>
</Property>
<Property name="hints">
<Value>Some hint here</Value>
<Value>blah blah blah</Value>
</Property>
</Pstructure>
</Property>
</q154>
</property>
<property name="q155">
<q155>
</Property name="intro" value="You get the idea ......."/>
</Property>
</q155>
</property>
</questions>
这就是我到目前为止所做的:
for f in "$1"*.xml
do
echo ::: Finding variables and options in $f...
vars=$(grep -nEo ".{0,30}{{[0-9]}}.{0,30}" $f | uniq)
if [ -n "$vars" ]
then
echo "$vars"
fi
done
这并不多,但我得到了变量列表,以及一些上下文(每边30个字符)和行号
我如何将这个变量列表传递给某个函数或方法,以获取其余缺少的信息,从而获得上面发布的输出
PS:这不一定要用grep完成,任何其他方法都可以,只要它打印相同的输出
编辑1:
如果我将需求分为多个步骤,将如下所示:
user@debian: ~/projectx$ ./myscript.sh questions01.xml
::: Finding variables and options in questions01.xml...
96: Based on the information, {{1}} is older than {{2}}
97: ...op1
99: ....choices
100: ..... Mary
101: ..... John
102: ..... Carl
113: ...op2
115: ....choices
116: ..... Albert
117: ..... Nicole
118: ..... Lizeth
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
190: The winner of the race was {{1}}
191: ...op1
193: ....choices
194: ..... Lewis Hammilton
195: ..... Valtteri Bottas
196: ..... Daniel Ricciardo
197: ..... Kimi Raikkonen
#!/bin/bash
cat -n $* | perl -ne '
print "::::::::::::::::::\n$_" if /<Property name="intro"/;
print if /"op\d"/../"correct-indices"/;
' | perl -ne '
next if /<Pstructure>/ || m{</Property>} || /"correct-indices">/;
s/"intro"\s+value="//;
s/"(op\d+)">/$1/;
s/<Property name=//;
s/"choices">/choices/;
s{<value>}{}i;
s{</value>}{}i;
s{"/>}{};
print;
' | perl -ne '
s/\s+(.+?\{\{\d\}\}.+)/$1/;
s/\s+(op\d)/...$1/;
s/\s+choices/....choices/;
s/^\s+(.+?)/.....$1/;
print;
' | perl -pe '
s/^(\.+?)(\d+)\t\s+/$2: $1/;
s/\t\s+/: /;
s/^\.+(\d+)(\.+?)/$1: $2/;'
如果我理解您试图实现的目标,那么即使使用适当的XML感知工具(可能是XSLT处理器解决方案),也很难做到这一点。阅读这里的一些答案
xmlstarlet
,并单独使用XSLT作为搜索词,看看我的意思。我认为您需要有2-4个独立的流程,每个流程都开发解决方案的一个阶段,然后您需要将它们“粘合”在一起。这是一个很好的学习练习,但如果你这样做是为了工作,最好与你的老板谈谈如何获得时间/资源来推动工作。祝你好运此外,如果您还没有与XML数据结婚,请考虑重新定义可以用来存储/检索/操作数据的工具。(您还可以使用支持XML的SQL数据库。)这看起来更像是一个带有SQL数据库后端(IMHO!)的网页。祝你好运。谢谢你@Sheller这确实是为了工作,但这是为了让我自己更容易。当显示“问题”和“选项”时,我试图检查语法,因此整个句子都有意义,例如,如果选项之一是复数,而前面的to be动词是单数,那么我必须将动词移到选项中,以便语法正确(例如,“winner was”将被编辑为“the”)…所以,问题“winner was”的这一部分必须转移到选项“winner was…”和“winner was…”哇,这一添加本身就是一个单独的问题。您似乎知道一些XML以及功能与严格要求之间的权衡,但我在S.O.上看到的Q/a。从XML专家那里得到了帮助,包括一个编码尝试(XSLT或xmlstarlet)解决问题。(我只阅读XML Qs,没有资格回答)。StackOverflow基于“一个编码问题”和“一个Cannonic答案”的思想“。你的Q有太多的部分。我建议把它分成多个Q,每个Q都是一个小的独立Q。包括你解决这个问题的最佳尝试,你会发现我并没有试图自动进行语法检查。总而言之,我只想能够将一个文件名(XML)传递给一个脚本(SH)并获得变量{1}”我可以查看是否有语法错误,然后决定是打开XML文件并手动编辑,还是继续其他文件。
::::::::::::::::::
5: Based on the information, {{1}} is older than {{2}}
6: ...op1
8: ....choices
9: .....Mary
10: .....John
11: .....Carl
22: ...op2
24: ....choices
25: .....Albert
26: .....Nicole
28: .....Lizeth