使用 sed 和 jq 在 属性 中替换 json 项
Make replacements in a property of a json item using sed and jq
我有一个包含 json 项列表的文件(每行一个),如下所示:
{ name: "Bob", location: "Boston, MA" }
{ name: "Peter", location: "San Francisco, CA" }
{ name: "Jane", location: "New York City, NY" }
比方说,我想在位置 属性 中用 Massachussetts
替换 MA
。我知道我可以使用 sed 's/MA/Massachussetts'
但这也会替换 name
字段中的每个 MA
。
有没有办法从命令行执行此操作,例如使用 jq
?
您可以试试下面的方法。
$ sed 's/\(\blocation: \+"[^,]*, *\)MA"/Massachussetts"/g' file
{ name: "Bob", location: "Boston, Massachussetts" }
{ name: "Peter", location: "San Francisco, CA" }
{ name: "Jane", location: "New York City, NY" }
或
$ sed 's/\(\blocation: \+"[^"]*\)\bMA/Massachussetts/g' file
{ name: "Bob", location: "Boston, Massachussetts" }
{ name: "Peter", location: "San Francisco, CA" }
{ name: "Jane", location: "New York City, NY" }
在当前 public 版本的 jq (1.4) 中,没有进行正则表达式替换的选项。然而,这将在下一个版本中改变。
sub 过滤器允许您对字符串进行正则表达式替换。然后你可以这样做:
.location |= sub("MA$"; "Massachussetts")
不过,您必须进行一些创造性操作才能允许多种选择。
这是一个解决方案,假设您的数据是干净的并且您需要的替换是有限的。
.location = (
{
"Boston, MA": "Boston, Massachussettts",
"San Francisco, CA": "San Francisco, California",
"New York City, NY": "New York City, New York"
}[.location] // .location
)
如果 filter.jq
包含上述过滤器并且 input.json
包含
{ "name": "Bob", "location": "Boston, MA" }
{ "name": "Peter", "location": "San Francisco, CA" }
{ "name": "Jane", "location": "New York City, NY" }
{ "name": "Unknown", "location": "Unknown" }
然后
jq -M -c -f filter.jq input.json
会产生
{"name":"Bob","location":"Boston, Massachussettts"}
{"name":"Peter","location":"San Francisco, California"}
{"name":"Jane","location":"New York City, New York"}
{"name":"Unknown","location":"Unknown"}
注意如果查找失败,使用 //
保持位置不变。
我有一个包含 json 项列表的文件(每行一个),如下所示:
{ name: "Bob", location: "Boston, MA" }
{ name: "Peter", location: "San Francisco, CA" }
{ name: "Jane", location: "New York City, NY" }
比方说,我想在位置 属性 中用 Massachussetts
替换 MA
。我知道我可以使用 sed 's/MA/Massachussetts'
但这也会替换 name
字段中的每个 MA
。
有没有办法从命令行执行此操作,例如使用 jq
?
您可以试试下面的方法。
$ sed 's/\(\blocation: \+"[^,]*, *\)MA"/Massachussetts"/g' file
{ name: "Bob", location: "Boston, Massachussetts" }
{ name: "Peter", location: "San Francisco, CA" }
{ name: "Jane", location: "New York City, NY" }
或
$ sed 's/\(\blocation: \+"[^"]*\)\bMA/Massachussetts/g' file
{ name: "Bob", location: "Boston, Massachussetts" }
{ name: "Peter", location: "San Francisco, CA" }
{ name: "Jane", location: "New York City, NY" }
在当前 public 版本的 jq (1.4) 中,没有进行正则表达式替换的选项。然而,这将在下一个版本中改变。
sub 过滤器允许您对字符串进行正则表达式替换。然后你可以这样做:
.location |= sub("MA$"; "Massachussetts")
不过,您必须进行一些创造性操作才能允许多种选择。
这是一个解决方案,假设您的数据是干净的并且您需要的替换是有限的。
.location = (
{
"Boston, MA": "Boston, Massachussettts",
"San Francisco, CA": "San Francisco, California",
"New York City, NY": "New York City, New York"
}[.location] // .location
)
如果 filter.jq
包含上述过滤器并且 input.json
包含
{ "name": "Bob", "location": "Boston, MA" }
{ "name": "Peter", "location": "San Francisco, CA" }
{ "name": "Jane", "location": "New York City, NY" }
{ "name": "Unknown", "location": "Unknown" }
然后
jq -M -c -f filter.jq input.json
会产生
{"name":"Bob","location":"Boston, Massachussettts"}
{"name":"Peter","location":"San Francisco, California"}
{"name":"Jane","location":"New York City, New York"}
{"name":"Unknown","location":"Unknown"}
注意如果查找失败,使用 //
保持位置不变。