我正在尝试使用 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
属性应该被移除
- 跨越对象层次结构的所有级别
- 应容忍空格变化
最佳答案
使用合适的 JSON 解析器,如 jq
通常是最好的选择e(见下文),但如果安装实用程序不是一个选项,试试这个 GNU sed
命令:
$ sed -zr 's/,\s*"country":[^\n]+//g' test.json
{
"name":"John",
"age":"16"
}
-z
通过NUL
将输入拆分为记录,在这种情况下意味着读取整个文件一次,这使得跨行替换成为可能。-r
启用扩展正则表达式以获得具有更多功能的更现代的语法。s/,\n"country":\s*//g
替换所有出现的逗号,后跟一个(可能为空的)空格(可能包括一个换行符)然后"country"
到该行末尾的空字符串,即有效地删除匹配的字符串。- 请注意,这假设同一行上没有其他属性或关闭
跟随这样的
country
属性。
- 请注意,这假设同一行上没有其他属性或关闭
展示基于jq
的更强大的解决方案.
Bertrand Martel's helpful answer包含一个 jq
解决方案,但是,它没有满足(稍后添加)替换输入对象层次结构中任何位置的 country
属性的要求。
在 v1.5.2
之前尚未发布的 jq
版本中,内置的 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
关于json - 如何用sed删除前一行的最后一个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40360307/