我有test.json
不同行长度的文件。一些虚构的例子:
{ a: 123, b: sd, c: x45, d: 1, e: '' }
{ a: 5, b: bfgg, c: x4c, d: 31, e: '' }
我想在d
- 部分之后剪切整个子字符串,并只为每一行返回:
{ a: 123, b: sd, c: x45 }
{ a: 5, b: bfgg, c: x4c }
我发现这里一个类似的问题并尝试使我的问题适应它:
echo test.json | sed 's/. d:/' > newtest.json
我需要对整个文件执行此操作,而不仅仅是一行。
答案1
如果您在命令行上进行了大量转换 json 的工作,那么非常值得您花时间获取 jq 工具并学习使用它。
虽然上面的答案表明您可以在不实际解析 json 的情况下进行最少的转换,但最终您将通过正则表达式重新发明一个有缺陷的 json 解析器,或者恢复使用您选择的语言中的本机 json 解析器。
jq 速度快,使用简单,是您工具箱中非常方便的工具。
BWT,您的测试数据是无效的 json,这将使上述解决方案变得复杂。如果你将其修复为
{ "a":123 , "b": "sd", "c": "x45", "d": 1, "e": "" }
{ "a":5 , "b": "bfgg", "c": "x4c", "d": 31, "e": "" }
那么这个 jq 命令就会满足你的要求
jq -c '{a,b,c}' test.json
{"a":123,"b":"sd","c":"x45"}
{"a":5,"b":"bfgg","c":"x4c"}
答案2
sed '/d:/s/, d:[^}]*/ /' test.json
它将遍历整个文件并删除每一行的d:
所有, d:.*
部分直到}
符号(}
符号将保留在该行上)。
答案3
@Rush 的答案使用sed
可能是解决此问题的最佳方法,但您awk
也可以使用以下方法来做到这一点:
$ awk -F ', d.* ' '{print $1, $2}' file.txt
{ a: 123, b: sd, c: x45 }
{ a: 5, b: bfgg, c: x4c }
上面用于awk
分割 上的数据, d.*
。这会生成 2 个数据字段,$1
其中$2
包含 AWK 拆分字符串所产生的数据。
答案4
假设您有一个包含一组对象的有效 JSON 文件,例如
{"a":123,"b":"sd","c":"x45","d":1,"e":"''"}
{"a":5,"b":"bfgg","c":"x4c","d":31,"e":"''"}
或同等的
{
"a": 123,
"b": "sd",
"c": "x45",
"d": 1,
"e": "''"
}
{
"a": 5,
"b": "bfgg",
"c": "x4c",
"d": 31,
"e": "''"
}
并且您想从每个对象中删除d
和键。e
使用jq
,一次删除一个键:
jq -c 'del(.d) | del(.e)' file.json
一次删除两个键:
jq -c 'del(.d, .e)' file.json
其中任何一个的结果都是
{"a":123,"b":"sd","c":"x45"}
{"a":5,"b":"bfgg","c":"x4c"}
第三种方法(不按名称提及实际键)是使用 将对象转换为“条目”列表to_entries
,然后删除最后两个条目并将列表转换回修改后的对象:
jq -c 'to_entries | del(.[-2:]) | from_entries' file.json
这最像问题文本所提出的内容,结果取决于对象中键的顺序。