将文本替换"scripts: {"
为以下字符串
"scripts": {
"watch": "tsc -w",
Run Code Online (Sandbox Code Playgroud)
在一个json
文件中。
我为源字符串和目标字符串创建了两个变量:
SRC='"scripts": {'
DST='"scripts": {
"watch": "tsc -w",'
Run Code Online (Sandbox Code Playgroud)
并运行以下命令:
sed "s/$SRC/$DST/" foo.json
Run Code Online (Sandbox Code Playgroud)
这已经失败了。
这次我转义了源字符串和目标字符串的双引号:
SRC="\"scripts\": {"
DST="\"scripts\": {
\"watch\": \"tsc -w\",
\"dev\": \"nodemon dist/index.js\","
Run Code Online (Sandbox Code Playgroud)
并运行与上面相同的命令,但失败了。
我使用以下命令尝试了如上定义的变量:
sed 's/'"$SRC"'/'"$DST"'/' foo.json
Run Code Online (Sandbox Code Playgroud)
这已经失败了。
所有这些尝试都产生了错误
unterminated 's' command
Run Code Online (Sandbox Code Playgroud)
出了什么问题?
假设您的 JSON 文档看起来像
{
"scripts": {
"other-key": "some value"
}
}
Run Code Online (Sandbox Code Playgroud)
...并且您想在.scripts
对象中插入一些其他键值对。然后你可以jq
用来做这个:
$ jq '.scripts.watch |= "tsc -w"' file.json
{
"scripts": {
"other-key": "some value",
"watch": "tsc -w"
}
}
Run Code Online (Sandbox Code Playgroud)
或者,
$ jq '.scripts += { watch: "tsc -w" }' file.json
{
"scripts": {
"other-key": "some value",
"watch": "tsc -w"
}
}
Run Code Online (Sandbox Code Playgroud)
这两个都将替换已经存在的.scripts.watch
条目。
请注意,其中键值对的顺序.scripts
并不重要(因为它不是数组)。
如果要保存,请将输出重定向到新文件。
将多个键值对添加到同一个对象:
$ jq '.scripts += { watch: "tsc -w", dev: "nodemon dist/index.js" }' file.json
{
"scripts": {
"other-key": "some value",
"watch": "tsc -w",
"dev": "nodemon dist/index.js"
}
}
Run Code Online (Sandbox Code Playgroud)
结合jo
创建需要添加到.scripts
对象的JSON :
$ jq --argjson new "$( jo watch='tsc -w' dev='nodemon dist/index.js' )" '.scripts += $new' file.json
{
"scripts": {
"other-key": "some value",
"watch": "tsc -w",
"dev": "nodemon dist/index.js"
}
}
Run Code Online (Sandbox Code Playgroud)
sed
适合解析面向行的文本。JSON 没有以换行符分隔的记录,sed
也不知道 JSON 的引用和字符编码规则等。要正确解析和修改这样的结构化数据集(或 XML、YAML,在某些情况下甚至是 CSV),您应该使用适当的解析器。
作为jq
在这种情况下使用的额外好处,您可以获得一些易于修改以满足您的需要的代码,并且同样易于修改以支持输入数据结构的更改。
Kusalananda说专用解析器是完成这项工作的正确工具是绝对正确的。然而,这也可以很容易地在sed
(至少在sed
理解GNU 的情况下\n
)中完成。通过尝试替换整个两行模式,您使事情变得更加复杂。相反,只需匹配目标字符串并在其后插入替换:
"scripts": {
Run Code Online (Sandbox Code Playgroud)
进而:
$ sed '/"scripts": {/s/$/\n "watch": "tsc -w",/' file
"scripts": {
"watch": "tsc -w",
Run Code Online (Sandbox Code Playgroud)
这意味着“如果此行与 string 匹配"scripts": {
,则将行尾替换为换行符 ( \n
) 后跟 "watch": "tsc -w",
。或者,您可以使用a
sed 命令附加文本:
$ sed '/"scripts": {/a\ "watch": "tsc -w",' file
"scripts": {
"watch": "tsc -w",
Run Code Online (Sandbox Code Playgroud)