sed는 중괄호가 마지막으로 발생하기 전에 개행을 추가합니까?

sed는 중괄호가 마지막으로 발생하기 전에 개행을 추가합니까?

마지막 중괄호 앞에 새 줄을 삽입하고 싶습니다. 내 텍스트 파일은 다음과 같습니다

 "accounts": {
    "0x0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": "0x0", "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
    "0x00Ea169ce7e0992960D3BdE6F5D539C955316432": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
 }

그래서 제가 하고 싶은 것은 accountsed 스크립트를 통해 새로운 것을 추가하는 것입니다.

새 계정은 다음과 같은 변수를 사용하여 지정됩니다.

"$ACCOUNT_ADDR": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }

답변1

sed작업에 잘못된 도구입니다. 올바른 도구 중 하나는 입니다 jq.

% 고양이 wibble.json
{
"계정": {
    "0x000000000000000000000000000000000000008": { "buildin": { "name": "alt_bn128_pairing", "active_at": "0x0", "가격": { "alt_bn128_pairing": { "base": 100000, "쌍": 8 000 0} } } },
    "0x00Ea169ce7e0992960D3BdE6F5D539C955316432": {"균형": "1606938044258990275541962092341162602522202993782792835301376"}
}
}
% ACCOUNT_ADDR="0xdeadbeeffeefdface0badd00dcacad0d0eeeeeeee"
% jq '."Account"."'"${ACCOUNT_ADDR}"'"."Balance"="42"' wibble.json
{
  "계정": {
    "0x0000000000000000000000000000000000000008": {
      "내장": {
        "이름": "alt_bn128_pairing",
        "activate_at": "0x0",
        "가격": {
          "alt_bn128_pairing": {
            "기본": 100000,
            "오른쪽": 80000
          }
        }
      }
    },
    "0x00Ea169ce7e0992960D3BdE6F5D539C955316432":{
      "균형": "1606938044258990275541962092341162602522202993782792835301376"
    },
    "0xdeadbeeffeefdface0badd00dcacad0d0eeeeeeee": {
      "균형": "42"
    }
  }
}
%

또한 둘러싸는 객체 없이 키+값 쌍이 있다는 사실도 발견했습니다. ☺

답변2

"계정"이 나타난 후에 한 줄을 추가할 수 있습니다.

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

관련 정보