Sil*_*ver 2 scripting ubuntu xml text-processing json
我在 txt 文件中有 5000 个问题,如下所示:
<quiz>
<que>The question her</que>
<ca>text</ca>
<ia>text</ia>
<ia>text</ia>
<ia>text</ia>
</quiz>
Run Code Online (Sandbox Code Playgroud)
我想在 Ubuntu 中编写一个脚本来转换所有问题,如下所示:
{
"text":"The question her",
"answer1":"text",
"answer2":"text",
"answer3":"text",
"answer4":"text"
},
Run Code Online (Sandbox Code Playgroud)
事实上,即使没有 Python 编程,你也可以摆脱这里,只需使用 2 个 unix 实用程序:
因此,假设您的 xml 位于 中file.xml
,jtm 会将其转换为以下 json:
bash $ jtm file.xml
[
{
"quiz": [
{
"que": "The question her"
},
{
"ca": "text"
},
{
"ia": "text"
},
{
"ia": "text"
},
{
"ia": "text"
}
]
}
]
bash $
Run Code Online (Sandbox Code Playgroud)
然后,应用一系列 JSON 转换,您可以得到所需的结果:
bash $ jtm file.xml | jtc -w'<quiz>l:[1:][-2]' -ei echo { '"answer[-]"': {} }\; -i'<quiz>l:[1:]' | jtc -w'<quiz>l:[-1][:][0]' -w'<quiz>l:[-1][:]' -s | jtc -w'<quiz>l:' -w'<quiz>l:[0]' -s | jtc -w'<quiz>l: <>v' -u'"text"'
[
{
"answer1": "text",
"answer2": "text",
"answer3": "text",
"answer4": "text",
"text": "The question her"
}
]
bash $
Run Code Online (Sandbox Code Playgroud)
不过,由于涉及 shell 脚本(echo
命令),它会比 Python 慢 - 对于 5000 个问题,我预计它会运行大约一分钟。(在未来的版本中,jtc
我计划甚至在静态指定的 JSON 中也允许插值,这样模板化就不需要外部 shell 脚本了,那么操作将会非常快)
如果您对jtc
语法感到好奇,可以在这里找到用户指南: https: //github.com/ldn-softdev/jtc/blob/master/User%20Guide.md
https://kislyuk.github.io/yq/xq
中的工具将您的 XML 转换为
{
"quiz": {
"que": "The question her",
"ca": "text",
"ia": [
"text",
"text",
"text"
]
}
}
Run Code Online (Sandbox Code Playgroud)
只需使用恒等过滤器 ( xq . file.xml
) 即可。
我们可以将其按摩成更接近您想要使用的形式
xq '.quiz | { text: .que, answers: .ia }' file.xml
Run Code Online (Sandbox Code Playgroud)
哪个输出
{
"text": "The question her",
"answers": [
"text",
"text",
"text"
]
}
Run Code Online (Sandbox Code Playgroud)
要修复该answers
位以便获得枚举键:
xq '.quiz |
{ text: .que } +
(
[
range(.ia|length) as $i | { key: "answer\($i+1)", value: .ia[$i] }
] | from_entries
)' file.xml
Run Code Online (Sandbox Code Playgroud)
这通过迭代节点并手动生成一组键和值来添加枚举键和answer
来自节点的值。然后使用它们将它们转换为真正的键值对,并将其添加到我们创建的原始对象 ( ) 中。ia
ia
from_entries
{ text: .que }
输出:
{
"text": "The question her",
"answer1": "text",
"answer2": "text",
"answer3": "text"
}
Run Code Online (Sandbox Code Playgroud)
如果您的 XML 文档quiz
在某个根节点下包含多个节点,则将上面的表达式更改为.quiz
对每个节点进行转换,并且您可能希望将结果对象放入数组中:jq
.[].quiz[]
xq '.[].quiz[] |
[ { text: .que } +
(
[
range(.ia|length) as $i | { key: "answer\($i+1)", value: .ia[$i] }
] | from_entries
) ]' file.xml
Run Code Online (Sandbox Code Playgroud)