かなり複雑な2つの式がありますが、jq
1つが別の1つの補数を返すことだけが異なります。つまり、2つの間の唯一の違いは、1つがselect(expression)
別のものが返すものを返すことですselect(expression|not)
。
単純化された例:
$ jq -n '$ARGS.positional[] | select( . > 2 )' --jsonargs 1 2 3 4 5
3
4
5
$ jq -n '$ARGS.positional[] | select( . > 2 | not )' --jsonargs 1 2 3 4 5
1
2
私のコードでこれら2つの異なる式を繰り返すのではなくjq
(各式は実際には数行の長さです)、単一の式に値を渡すことで2つの動作を切り替えることができます。これは非常に簡潔です。
どうすればいいですか?
実際のjq
コード(メッセージペイロードでエンコードされたファイルパスに基づいてRabbitMQメッセージをフィルタリング):
map(
# Add an array of pathnames that would match this message. This
# includes the pathnames of each parent directory, leading up to
# and including the pathname of the file itself.
.tmp_paths = [
# The full pathname is part of a base64-encodod JSON blob.
foreach (
.payload |
@base64d |
fromjson.filepath |
split("/")[]
) as $elem (
null;
. += $elem + "/";
.
)
] |
# The last element is the full file path and should not have a
# trailing slash.
.tmp_paths[-1] |= rtrimstr("/")
) |
[
# Match the pathnames given as positional command line arguments
# against the computed pathnames in the "tmp_paths" array in
# each message. Extract the messages with a match.
JOIN(
INDEX($ARGS.positional[]; .);
.[];
.tmp_paths[];
if (.[1:] | any) then
.[0]
else
empty
end
)
] |
# Deduplicate the extracted messages on the full pathname of the file.
# Then remove the "tmp_paths" array from each message and base64 encode
# them.
unique_by(.tmp_paths[-1])[] |
del(.tmp_paths) |
@base64
if
私は、ファイルパスが場所引数として指定されたパス名と一致するメッセージを抽出または削除するように、任意の方法でステートメントを変更する必要があると仮定します。
ベストアンサー1
ブール値をjq
式に渡し、if
- ステートメントを使用して選択したセットまたは対応する補数の戻り値を切り替えます。
$ jq -n --argjson yes true '$ARGS.positional[] | select( . > 2 | if $yes then . else not end )' --jsonargs 1 2 3 4 5
3
4
5
$ jq -n --argjson yes false '$ARGS.positional[] | select( . > 2 | if $yes then . else not end )' --jsonargs 1 2 3 4 5
1
2
より複雑なjq
式はif
ステートメントを変更します。
# Match the pathnames given as positional command line arguments
# against the computed pathnames in the "tmp_paths" array in
# each message. Depending on the $yes boolean variable, extract
# or discard matching messages.
JOIN(
INDEX($ARGS.positional[]; .);
.[];
.tmp_paths[];
if (.[1:] | any | if $yes then . else not end) then
.[0]
else
empty
end
)
if $yes then . else not end
これは、変数が$yes
集合を望むのか、それともその補数を望むのかについての「トグル」として機能できることに注意してください。単純化されたselect()
形式とより複雑な形式の両方で、JOIN()
このif
ステートメントはブールテスト結果に対して機能し、要素が結果セットの一部かどうかを判断します。