LoginSignup
17
8

More than 3 years have passed since last update.

コマンドライン上でJSONを上書き保存する

Last updated at Posted at 2020-01-22

やりたいこと

GithubActions上でJSONを書き換えるのにいい方法ないかなーと思ったことです。

console
% echo '[{"name":"hoge","age":"29"},{"name":"fuga","age":"30"}]' > test.json
% cat test.json | jq
[
  {
    "name": "hoge",
    "age": "29"
  },
  {
    "name": "fuga",
    "age": "30"
  }
]
% jq '.[1].age="25"' test.json # この結果でtest.jsonを上書きたい
[
  {
    "name": "hoge",
    "age": "29"
  },
  {
    "name": "fuga",
    "age": "25"
  }
]

できない方法

console
% cat test.json | jq '.[1].age="25"' > test.json
% cat test.json | jq # 空ファイルになる

stackoverflowのコメントより

シェルがコマンドラインを解釈した後、hoge.txt をオープンして 0 バイトにしてから cat を起動するので当然の結果です。実行したいコマンドラインの前に hoge.txt を一時ファイルにコピーして利用するか、実行結果を一時ファイルに出力したあと上書きする必要があります。

stackoverflowのコメントより

リダイレクトはコマンドが実行される前に shell が処理してしまってますから、コマンドが実行された時には既にファイルは空になっています。

簡単にできるわけではなさそう。

実現する方法

1.tmpを作って逃がす

違う名前だったら処理結果を出力できるので

console
% echo '[{"name":"hoge","age":"29"},{"name":"fuga","age":"30"}]' > test.json
% jq '.[1].age="25"' test.json > tmp && mv tmp test.json
% cat test.json | jq
[
  {
    "name": "hoge",
    "age": "29"
  },
  {
    "name": "fuga",
    "age": "25"
  }
]

2.黒魔術

悪くはなさそうだけど、何をやってるのか直感的じゃないですね。。。

console
% echo '[{"name":"hoge","age":"29"},{"name":"fuga","age":"30"}]' > test.json
% (rm test.json && jq '.[1].age="25"' > test.json) < test.json
% cat test.json | jq
[
  {
    "name": "hoge",
    "age": "29"
  },
  {
    "name": "fuga",
    "age": "25"
  }
]

3. sponge

macOSなら brew install moreutils した後で

console
% echo '[{"name":"hoge","age":"29"},{"name":"fuga","age":"30"}]' > test.json
% jq '.[1].age="25"' test.json | sponge test.json
% cat test.json | jq
[
  {
    "name": "hoge",
    "age": "29"
  },
  {
    "name": "fuga",
    "age": "25"
  }
]

後から読む人のことを考えたら1が良さそうです。
3はスッキリするけど、この為だけにインストールしなきゃなので…

参考

17
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
8