如何用sed删除前一行的最后一个字符

时间:2016-11-01 12:42:03

标签: json bash sed

我尝试使用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属性 - 跨越对象层次结构的所有级别 - 应该容忍空白变化

4 个答案:

答案 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
相关问题