リストにない項目を選択してフィルター処理するために jq を使用する方法は? 質問する

リストにない項目を選択してフィルター処理するために jq を使用する方法は? 質問する

jqではアイテムを選択できますリストはかなり簡単に作成できます:

$ echo '["a","b","c","d","e"]' | jq '.[] | select(. == ("a","c"))'

または、配列として取得したい場合:

$ echo '["a","b","c","d","e"]' | jq 'map(select(. == ("a","c")))'

しかし、すべてのアイテムを選択するにはどうすればいいのでしょうか?ないリストに載っていますか?確かに. != ("a","c")動作しません:

$ echo '["a","b","c","d","e"]' | jq 'map(select(. != ("a","c")))'
[
  "a",
  "b",
  "b",
  "c",
  "d",
  "d",
  "e",
  "e"
]

上記は、およびを除くすべての項目を2回表示し"a"ます"c

以下も同様です:

$ echo '["a","b","c","d","e"]' | jq '.[] | select(. != ("a","c"))'
"a"
"b"
"b"
"c"
"d"
"d"
"e"
"e"

フィルタリングするには一致するアイテムは?

ベストアンサー1

最もシンプルで堅牢な(jq バージョンに関して)アプローチは、組み込みを使用することです-

$ echo '["a","b","c","d","e"]' | jq -c '. - ["a","c"]'
["b","d","e"]

ブラックリストが非常に長く、重複が多数ある場合は、それらを削除するのが適切である可能性があります (例: を使用unique)。

バリエーション

この問題は、(jq 1.4以降では)indexと を使用しても解決できますnot。例:

["a","c"] as $blacklist
| .[] | select( . as $in | $blacklist | index($in) | not) 

または、コマンドラインから渡された変数を使用する場合 (jq --argjson blacklist ...):

.[] | select( . as $in | $blacklist | index($in) | not) 

リスト構造を保持するには、 を使用できますmap( select( ...) )

jq 1.5以降では、anyまたはを使用することもできますall。例:

def except(blacklist):
  map( select( . as $in | blacklist | all(. != $in) ) );

特殊なケース: 文字列

例えばjq の複数の値に基づいてエントリを選択する

おすすめ記事