notebook

都内でWEB系エンジニアやってます。

jqで条件にマッチしないデータをnotとselectで除外する

jqを使っていて「特定の文字列を含んでない」レコードをselectしたいみたいなケースの話

感覚的には条件式に!をつけて否定したものを条件として使いたかったがそういう書き方はできない

調べてみたら次のスレッドで言及されていた

jq - How to filter a json that does not contain - Stack Overflow

stackoverflow.com

true/false に対してパイプでnotに渡してあげればよいらしい

サンプルを用意していくつか試してみる

  • sample.json
[
  {
    "name": "hoge 1.1.1",
    "flag": true
  },
  {
    "name": "fuga 2.1.1",
    "flag": false
  },
  {
    "name": "3.3.3",
    "flag": true
  }
]

flagだけ取り出してみる

$ cat sample.json | jq '.[]|.flag'
true
false
true

真偽値をnotを使って反転させる

$ cat sample.json | jq '.[]|.flag|not'
false
true
false

flag: falseのデータだけ抜き出してみる

$ cat sample.json | jq '.[]|select(.flag|not)'
{
  "name": "fuga 2.1.1",
  "flag": false
}

こういう感じで使えるのねということがわかったのであとは真偽値を返す関数を前段でかませてあげればやりようはいくらでもありそう

containsを使ってnamehogeという文字列が含まれ「ない」か

cat sample.json | jq '.[]|contains({name: "hoge"})|not'
false
true
true

namehogeが含まれ「ない」データを抜き出す

$ cat sample.json | jq '.[]|select(contains({name: "hoge"})|not)'
{
  "name": "fuga 2.1.1",
  "flag": false
}
{
  "name": "3.3.3",
  "flag": true
}

manualが検索しづらかったので覚えておきます