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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 12:05:48  来源:igfitidea点击:

editing a JSON file with sed

regexjsonbashsed

提问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 sedcommand 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 jqbecause the file will be edited on a server and I cannot install jqon 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 shmodule of python and just write the script in python:

不过就我个人而言,我更喜欢使用shpython的模块,直接用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, sedis 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 -iswitch 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 jqor 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 \1we 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。:-)