bash 使用 sed 编辑 JSON 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27714487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
editing a JSON file with sed
提问by Tom Oakley
I need to edit a JSON file, using sed
, to add some data in to the file. The JSON is as follows:
我需要编辑一个 JSON 文件,使用sed
, 将一些数据添加到文件中。JSON 如下:
{
'name':
// more attributes that are already filled in
}
I have written this sed
command to try and do it:
我写了这个sed
命令来尝试这样做:
sed "s/(\'name\':)/\"hello\"\,/g" /path/to/file.json
However, I keep getting this error:
但是,我不断收到此错误:
sed: not defined in the RE
The expected results are:
预期的结果是:
{
'name': "hello",
// more attributes here, left untouched
}
I know this is a bad way of doing it, but I don't think I am able to use tools such as jq
because the file will be edited on a server and I cannot install jq
on the server. If anyone has a better solution i'd be very interested to hear it. Thank you!
我知道这是一种糟糕的做法,但我认为我无法使用工具,例如jq
因为文件将在服务器上编辑而我无法jq
在服务器上安装。如果有人有更好的解决方案,我会非常有兴趣听到它。谢谢!
采纳答案by djhaskin987
Use python, it's so much easier and on most POSIX systems:
使用 python,它更容易并且在大多数 POSIX 系统上:
#!/usr/bin/python
import json
jsonObject = json.load(filename)
jsonObject['name'] = "hello"
json.dump(filename, jsonObject)
And run it:
并运行它:
python parse_json.py
EDIT: To use this in a bash setting, use a here document:
编辑:要在 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
The foregoing script uses a here document to create a python script on the fly and run it to alter the JSON, then removes the parse json script afterwards.
上述脚本使用 here 文档动态创建 python 脚本并运行它来更改 JSON,然后删除解析 json 脚本。
Personally, though, I prefer to use the sh
module of python and just write the script in python:
不过就我个人而言,我更喜欢使用sh
python的模块,直接用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")
Between python's sh
(command execution), os
(file manipulation), shutil
(recursive file manipulation) and re
(regex) modules, I find bash's functionality may be generally completely replaced.
在 python 的sh
(命令执行)、os
(文件操作)、shutil
(递归文件操作)和re
(正则表达式)模块之间,我发现 bash 的功能通常可以完全替代。
回答by Gilles Quenot
As you stated, sed
is not the right tool here, instead, use a proper JSON parser :
正如您所说,sed
这里不是正确的工具,而是使用适当的 JSON 解析器:
INPUT json
输入json
$ cat json
{
"name": "foobar"
}
using jq:
使用jq:
$ jq '.name |= "qux"' json | tee json
(the latest with teework with small files)
(最新的与tee一起使用小文件)
or using perl:
或使用perl:
perl -i -MJSON -0ne '
my $DS = decode_json $_;
$DS->{name} = "qux";
print encode_json $DS
' json
remove the -i
switch if you want to test the command without editing the file in place
-i
如果要在不就地编辑文件的情况下测试命令,请删除开关
OUTPUT json
输出 json
$ cat json
{
"name": "qux"
}
回答by Wintermute
You have the backslashes in the wrong places. '
does not need to be escaped, but the parentheses do. This works:
你在错误的地方有反斜杠。'
不需要转义,但括号可以。这有效:
sed "s/\('name':\)/\"hello\"\,/g" /path/to/file.json
Note: I'm assuming that file.json is not a json file but a specially crafted template, otherwise this substitution wouldn't make any sense (the result would not be JSON). Working on JSON files with sed is quite certainly a bad idea, so if you're trying to modify JSON rather than generating it, take a look at jq
or so instead.
注意:我假设 file.json 不是一个 json 文件而是一个特制的模板,否则这个替换没有任何意义(结果不会是 JSON)。使用 sed 处理 JSON 文件肯定是一个坏主意,因此如果您尝试修改 JSON 而不是生成它,请查看jq
左右。
回答by Arjun Mathew Dan
sed "s/'name':/& \"hello\",/" File
Almost similar to Wintermutes's answer, but here we are avoiding the (grouping)
and therefore instead of \1
we use & (pattern matched)
. Also, global substitution (g)
is not required if only one occurence of 'name':
in each line. I'm not sure if sed is the right tool for the job though. I do not know JSON yet. :-)
几乎与 Wintermutes 的答案相似,但在这里我们避免使用(grouping)
,因此\1
我们使用& (pattern matched)
. 此外,global substitution (g)
如果'name':
每行只出现一次,则不需要。不过,我不确定 sed 是否适合这项工作。我还不知道 JSON。:-)