我想在最后一次出现的大括号之前插入一个新行。我的文本文件看起来像这样
"accounts": {
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0x00Ea169ce7e0992960D3BdE6F5D539C955316432": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
}
所以我想做的是account
通过 sed 脚本添加一个新的。
请注意,新帐户将使用变量指定,例如:
"$ACCOUNT_ADDR": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
答案1
sed
是这项工作的错误工具。正确的工具之一是jq
.
% 猫 wibble.json { “账户”:{ "0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 8000 0 } } } }, “0x00Ea169ce7e0992960D3BdE6F5D539C955316432”:{“余额”:“1606938044258990275541962092341162602522202993782792835301376”} } } % ACCOUNT_ADDR="0xdeadbeeffeefdface0badd00dcacad0d0eeeeeeee" % jq '."账户"."'"${ACCOUNT_ADDR}"'"."余额"="42"' wibble.json { “账户”:{ “0x0000000000000000000000000000000000000008”:{ “内置”: { “名称”:“alt_bn128_pairing”, “activate_at”:“0x0”, “价钱”: { “alt_bn128_pairing”:{ “基数”:100000, “对”:80000 } } } }, “0x00Ea169ce7e0992960D3BdE6F5D539C955316432”:{ “余额”:“1606938044258990275541962092341162602522202993782792835301376” }, “0xdeadbeeffeefdface0badd00dcacad0d0eeeeeeee”:{ “余额”:“42” } } } %
它还发现了这样一个事实:您有一个没有封闭对象的键+值对。 ☺
答案2
您可以在“accounts”出现后添加一行,
sed "/accounts/ a\
\"$ACCOUNT_ADDR\": { \"balance\": \"1606938044258990275541962092341162602522202993782792835301376i\" }
" file
("
转义,插入变量)
sed "s/^ }$/ \"$ACCOUNT_ADDR\": { \"balance\": \"1606938044258990275541962092341162602522202993782792835301376i\" }\n }/g" file
将替换您的}
行并打印两行。
循环运行sed -i ...
更改文件:
$ cat file
"accounts": {
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0x00Ea169ce7e0992960D3BdE6F5D539C955316432": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
}
$ cat script.sh
#!/bin/bash
for i in $(seq 1 5); do
ACCOUNT_ADDR="account_"$i
sed -i "/accounts/ a\
\"$ACCOUNT_ADDR\": { \"balance\": \"1606938044258990275541962092341162602522202993782792835301376i\" }
" file
done
$ ./script.sh
$ cat file
"accounts": {
"account_5": { "balance": "1606938044258990275541962092341162602522202993782792835301376i" }
"account_4": { "balance": "1606938044258990275541962092341162602522202993782792835301376i" }
"account_3": { "balance": "1606938044258990275541962092341162602522202993782792835301376i" }
"account_2": { "balance": "1606938044258990275541962092341162602522202993782792835301376i" }
"account_1": { "balance": "1606938044258990275541962092341162602522202993782792835301376i" }
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"0x00Ea169ce7e0992960D3BdE6F5D539C955316432": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
}
答案3
我时不时地喜欢 sed 挑战:使用ACCOUNT_ADDR=1234
:
sed -n -e '
x
$ i\
"'"$ACCOUNT_ADDR"'": {"balance":0},
2,$ p
$ { x; p }
' file
"accounts": {
"0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
"1234": {"balance":0},
"0x00Ea169ce7e0992960D3BdE6F5D539C955316432": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
}
这使用x
将当前行存储到保留空间中,以成为下一个周期中的“上一个”行。
正如其他地方提到的,用于sed -i
就地保存编辑
您可以通过反转文件并使用更简单的 sed 命令获得相同的结果:
temp=$(mktemp)
tac file | sed '2a\
"'"$ACCOUNT_ADDR"'": {"balance":0},
' | tac > "$temp" && mv "$temp" file