yqを使って、配列内のあるKeyが特定の値を持っている場合にその配列内の値を変更する方法

すっごい長いタイトル。でも表題通り。
yamlでこういうことがしたいんだけど、ってときにドキュメントとにらめっこしたがすぐに解決できなかったので、その備忘録として記載。
よく考えれば単純。
なお、yqはjqのwrapperではない方のversion 4
どういうことか、詳しくは以下

yqのversionによって結構違うのでそこだけ注意
jqのwrapperなyqもあれば、そうじゃない方のyqもある
じゃない方のver4
https://github.com/mikefarah/yq
下記コマンドは現時点での最新バージョンの4.27.7を利用している

したいことはどういうことかの実例を見るとわかりやすい
以下のようなhttpリクエストを作成するhttp.yamlがある

http:
  Header:
  - Key: header1
    Value: value1
  - Key: header2
    Value: value2
  - Key: header3
    Value: value3
  Method: GET

こんな感じでhttpリクエストを生成するためのyamlファイル
これのhttp.Header[].Keyがheader2の場合のValueの値value2をyqコマンドを使って書き換えたい

結論としてはこう

$ yq '.http.Header[] | select(.Key == "header2").Value = "hoge" | [.] ' http.yaml | yq eval-all 'select(fileIndex==0).http.Header = select(fileIndex==1) | select(fileIndex==0)' http.yaml -
http:
  Header:
    - Key: header1
      Value: value1
    - Key: header2
      Value: hoge
    - Key: header3
      Value: value3
  Method: GET

上書きするなら最後のyqコマンドに -i オプションを追加

半日考えて解決しなかったが、わかってしまえばなんてことない。
select().key = “value” なんてことができるのに組み合わせて
.[]で配列じゃない状態(?)で渡した後、また配列にするため[.]がずっとわからなかった

なんでできないんだと結構頭に来たのでこうやって備忘録として書いた
が、ブログを書きながら思った。
そもそもなんでjqのwrapperじゃない方でやってるんだろう
jqの方が一般的で、jqコマンドのほうが使い慣れている人が多いだろうから、yqもjqのwrapperの方が良かっただろう

また今度ね!

な!

https://www.youtube.com/watch?v=xm-iWo2uEIM&t=200s

200s が素晴らしい

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)