我尝试使用sed删除前一行的最后一个字符的行:
我有一个json文件:
{
"name":"John",
"age":"16",
"country":"Spain"
}
我想删除所有条目的国家/地区,为此我必须删除前一行的json语法的逗号。
我使用这种模式:
sed '/country/d' test.json
sed -n '/resolved//.$//{x;d;};1h;1!{x;p;};${x;p;}' test.json
编者注释:
OP随后澄清了以下附加要求,这些要求使一些现有答案无效:
- 应删除多个出现的country
属性
- 跨越对象层次结构的所有级别
- 应该容忍空白变化
答案 0 :(得分:2)
如前所述,您应该考虑使用JSON解析器来解析JSON。
如果说的话你可以啜饮整个文件,删除换行符然后替换 accordantly:
$this->validate($request, [
'name' => 'required_without_all:hair_style, hair_color, options',
]);
故障:
$ sed ':a;N;$!ba;s/\n//g;s/,"country"[^}]*//' test.json
{"name":"John","age":"16"}
答案 1 :(得分:2)
使用jq
等适当的JSON解析器通常是最好的选择 e(见下文),但如果无法安装实用程序,请尝试使用 GNU sed
命令:
$ sed -zr 's/,\s*"country":[^\n]+//g' test.json
{
"name":"John",
"age":"16"
}
-z
将输入分成NUL
s的记录,在这种情况下意味着立即读取整个文件,这样就可以行换人。
-r
启用扩展正则表达式,以获得具有更多功能的更现代的语法。
s/,\n"country":\s*//g
替换所有出现的逗号后跟一个(可能是空的)空格运行(包括可能是换行符),然后"country"
替换该行结尾的空字符串,即有效地删除匹配的字符串。
}
跟随这样的country
属性。演示基于jq
的更强大的解决方案。
Bertrand Martel's helpful answer包含jq
解决方案,但是,该解决方案无法满足在任何地方替换country
属性的要求(稍后添加 )输入对象层次结构。
在尚未发布的版本jq
高于v1.5.2
的情况下,内置walk/1
功能将可用,从而实现以下简单解决方案:
# Walk all nodes and remove a "country" property from any object.
jq 'walk(if type == "object" then del (.country) else . end)' test.json
在v1.5.2
及以下,您可以自己定义walk
的简化版本:
jq '
# Define recursive function walk_objects/1 that walks all objects in the
# hierarchy.
def walk_objects(f): . as $in |
if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk_objects(f)) } ) | f
elif type == "array" then map( walk_objects(f) )
else . end;
# Walk all objects and remove a "country" property, if present.
walk_objects(del(.country))
' test.json
答案 2 :(得分:2)
这可能适合你(GNU sed):
sed 'N;s/,\s*\n\s*"country".*//;P;D' file
在模式空间中读取两行并删除替换字符串。
N.B。允许在线的任一侧留出空格。
答案 3 :(得分:1)
您可以使用jq
之类的JSON解析器来解析json文件。以下内容将返回没有country
字段的文档,并在result.json
中写下新文档:
jq 'del(.country)' file.json > result.json