使用sed编辑JSON文件

时间:2014-12-31 00:17:52

标签: regex json bash sed

我需要使用sed编辑JSON文件,将一些数据添加到文件中。 JSON如下:

{
  'name':
  // more attributes that are already filled in 
}

我已编写此sed命令尝试执行此操作:

sed "s/(\'name\':)/\1\"hello\"\,/g" /path/to/file.json

但是,我一直收到这个错误:

sed: \1 not defined in the RE

预期结果如下:

{
  'name': "hello",
  // more attributes here, left untouched
}

我知道这是一种不好的方法,但我认为我无法使用jq之类的工具,因为该文件将在服务器上进行编辑而我无法安装{{1}在服务器上。如果有人有更好的解决方案,我会非常有兴趣听到它。谢谢!

4 个答案:

答案 0 :(得分:8)

正如您所说,sed不是正确的工具,而是使用正确的JSON解析器:

INPUT json

$ cat json
{
  "name": "foobar"
}

使用

$ jq '.name |= "qux"' json | tee json 

(最新的使用小文件)

或使用

perl -i -MJSON -0ne '
    my $DS = decode_json $_;
    $DS->{name} = "qux";
    print encode_json $DS
' json

如果要在不编辑文件的情况下测试命令,请删除-i开关

OUTPUT json

$ cat json
{
  "name": "qux"
}

答案 1 :(得分:2)

你在错误的地方有反斜杠。 '不需要转义,但括号可以转义。这有效:

sed "s/\('name':\)/\1\"hello\"\,/g" /path/to/file.json

注意:我假设file.json不是json文件而是特制模板,否则这种替换没有任何意义(结果不是JSON)。使用sed处理JSON文件肯定是一个坏主意,因此如果您尝试修改JSON而不是生成JSON,请改为查看jq左右。

答案 2 :(得分:1)

使用python,它在大多数POSIX系统上都非常简单:

#!/usr/bin/python
import json
jsonObject = json.load(filename)
jsonObject['name'] = "hello"
json.dump(filename, jsonObject)

运行它:

python parse_json.py

编辑:要在bash设置中使用此功能,请使用此处的文档:

#!/bin/sh

# ...

# set the name variable to something
name=VALUE

# ...

# and use it in a here document
parse_json_script=$(mktemp parse_json.XXXX.py)
cat > $parse_json_script << SCRIPT
#!/usr/bin/env python
import json
jsonObject = json.load(filename)
# You can use bash variables in here documents.
# the line below uses the bash variable `name` and inserts it into the python script
jsonObject['name'] = "$name"
print(jsonObject['name'])
json.dump(filename, jsonObject)
SCRIPT
python $parse_json_script && rm $parse_json_script

上述脚本使用here文档动态创建python脚本并运行它来改变JSON,然后删除解析json脚本。

但就个人而言,我更喜欢使用python的sh模块,只需在python中编写脚本:

#!/usr/bin/python
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals 
import sh

# now you can call any command as if it were a python function
sh.ls("-lah") # `ls -lah`, but maybe you use python's `os` module instead
sh.rsync("-avHAX","foo","bar")

在python的sh(命令执行),os(文件操作),shutil(递归文件操作)和re(正则表达式)模块之间,我发现了bash的功能通常可以完全取代。

答案 3 :(得分:1)

sed "s/'name':/& \"hello\",/" File

几乎与Wintermutes的答案相似,但我们在这里避开(grouping),因此我们使用\1代替& (pattern matched)。此外,如果每行只发生一次global substitution (g),则不需要'name':。我不确定sed是否适合这项工作。我还不知道JSON。 : - )