sed 在最后一次出现大括号之前添加换行符?

sed 在最后一次出现大括号之前添加换行符?

我想在最后一次出现的大括号之前插入一个新行。我的文本文件看起来像这样

 "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

相关内容