我正在尝试编写一个命令行界面,它将删除 json 文件列表中的特定部分/代码行。顺便说一句,json文件位于主目录的子文件夹中
我对此很陌生,但这是迄今为止我能想到的代码 -find -name "*.json" | xargs sed -i "map"
但我拥有的一些 json 文件,其格式略有不同
到目前为止,我在列表中看到以下 2 种格式:
{
"tags": {},
"map": {
"KPA": {
"State": True,
"namespace": "KPA01"
}
}
}
或者
{
"tags": {
"type": [
"char"
],
"dynamic": true
},
"map": {
"KPA01": {
"State": True,
"namespace": "KPA01"
}
}
}
基本上,我试图省略它所具有的地图部分,以便它只显示标签部分,但逗号和[]
/的存在{}
让我很难。所以我的输出结果应该是这样的:
{
"tags": {}
}
或者
{
"tags": {
"type": [
"char"
],
"dynamic": true
}
}
这可以在命令行界面中执行吗?我听说 jq 可能能够做到这一点,但是,当我尝试执行时,jq '.map' test.json
我进入了parse error: ':' not as part of an object at line 2, column 11
我的终端。同样,如果我使用的是,它似乎也会发出错误jq玩在线的..
有任何想法吗?
答案1
首先,更改True
为true
.总的来说,这非常有效:
#!/usr/bin/python
import sys
import json
inputfile = sys.argv[1]
with open(inputfile,'r') as myfile:
obj = json.loads(myfile.read().replace('True','true'))
if "map" in obj:
del obj["map"]
json.dump(obj,sys.stdout,indent=4,separators=(',',': '))
这会写入标准输出。
编辑:以前的就地版本似乎有些危险。最好这样做:
#!/usr/bin/python
import sys
import json
inputfile = sys.argv[1]
with open(inputfile,'r') as myfile:
obj = json.loads(myfile.read().replace('True','true'))
if "map" in obj:
del obj["map"]
with open(inputfile,'w') as myfile:
json.dump(obj,myfile,indent=4,separators=(',',': '))
因为脚本实际上知道什么是有效的 JSON,所以如果遇到无效代码,它会抛出异常,而不是产生不可预测的输出。
这适用于 python 3,只是让你知道。
编辑2:
你可以用任何你喜欢的方式修改对象,Json的目的正是对象的序列化。将它们视为关联数组并为它们提供您想要的任何值。例如,您可以这样做:
#add a new string on the "ground" level
obj["new_key"]="lol"
#add a new subarray, with properties of different types
obj["this_is_array"]={"a": 3, "b": 16, "c": "string", "d": False }
#modify the value of existing field
obj["new_key"]="new value"
#insert into subarray (test if it exists first)
if "this_is_array" in obj:
obj["this_is_array"]["e"]=42
答案2
如果您处理真的>真的正如其他地方提到的并获取该jq
工具,您可以执行以下操作:
jq '{tags}' <infile
例如,将您的示例之一复制到我的剪贴板后:
xsel -bo | sed 's/True/true/g' | jq '{tags}'
输出:
{
"tags": {
"type": [
"char"
],
"dynamic": true
}
}
答案3
我发现同样的错误:
parse error: Invalid numeric literal at line 5, column 26
我不习惯json但我认为True
应该是小写的,如true
,这样你就可以运行珀尔单行修复它,然后用于jq
过滤掉map
密钥,例如:
perl -pe 's/(\W)T(rue)/$1t$2/g' file1.json | ./jq 'del(.map)'
对于第一个例子,结果是:
{
"tags": {}
}
和:
perl -pe 's/(\W)T(rue)/$1t$2/g' file2.json | ./jq 'del(.map)'
对于第二个,结果是:
{
"tags": {
"type": [
"char"
],
"dynamic": true
}
}
答案4
问题很老了,但是为了选项的完整性,这里是联合TC基于的解决方案:
bash $ jtc -pw'<map>l+0' input.json
{
"tags": {
"dynamic": true,
"type": [
"char"
]
}
}
bash $
- 它会找到所有标签
"map"
并清除它们(同时保留 json 的其余部分)