jqでこれらの配列エントリを削除できないのはなぜですか?

jqでこれらの配列エントリを削除できないのはなぜですか?

次のコマンドを実行します。

echo '["tag1", "[[Super", "Duppa", "Database", "Analyst]]", "tag2"]' | jq -f ~/somefilter.jq

jqフィルタ(~/somefilter.jq):

def hasOne(x): x | (startswith("[[") or endswith("]]") ); 
def looparr(r): [ r | keys[] as $i | r[$i] | select(hasOne(.)) | $i ] ; 
. as $arrray | $arrray |= .+ [ . as $arr | looparr($arr) | .[0] as $str | .[1] as $ed | $arr[$str:$ed+1] | join(" ") ] | del(.[$str:$ed+1])

del(.[$str:$ed+1])接続したばかりの文字列を自分のアイテムとして削除したらどうなりますか?

代わりに、次のエラーが発生します。

jq: error: str/0 is not defined at <top-level>, line 3:
. as $arrray | $arrray |= .+ [ . as $arr | looparr($arr) | .[0] as $str | .[1] as $ed | $arr[$str:$ed+1] | join(" ") ] | del(.[$str:$ed+1])
jq: error: ed/0 is not defined at <top-level>, line 3:
. as $arrray | $arrray |= .+ [ . as $arr | looparr($arr) | .[0] as $str | .[1] as $ed | $arr[$str:$ed+1] | join(" ") ] | del(.[$str:$ed+1])

| del(.[$str:$ed+1])最後に削除して置き換えると、| .出力は次のようになります。

[
  "tag1",
  "[[Super",
  "Duppa",
  "Database",
  "Analyst]]",
  "tag2",
  "[[Super Duppa Database Analyst]]"
]

私が望む出力は次のとおりです。

[
  "tag1",
  "tag2",
  "[[Super Duppa Database Analyst]]"
]

定数を追加しようとするとうまくいきますが、スクリプトは非常に柔軟になりません(おそらく現在ではそうではありません)。

$strにアクセスできない理由がありますか$ed

答え1

問題は、これらの変数がにあるため範囲外です[]jqしかし、以下はコードを複製して正解を提供するようです。

 . as $arr |
 looparr($arr) | 
 .[0] as $str |
 .[1] as $ed |
 $arr |
 del(.[$str:$ed+1])
+ [
 . as $arr |
 looparr($arr) | 
 .[0] as $str |
 .[1] as $ed |
 $arr[$str:$ed+1] |
 join(" ")
]

答え2

式の問題は変数jqの範囲に関連しています$str$edmeuhがすでに述べたように。これは配列式内で定義されるため、その式内で範囲が指定されます。に電話すると、もはやdel(.[$str:$ed+1])範囲に含まれなくなります。

reduceアドインを定義する必要がない次の方法で代替ソリューションを提供しました。

reduce .[] as $item ([];
        if      isempty(.[])
        or      (last | startswith("[[") | not)
        or      (last | endswith("]]"))
        then
                # Current item is to be added to the list
                # as a separate list item.
                .       += [$item]
        else
                # Current item is to be appended to the last
                # list item (with a delimiting space).
                last    += " " + $item
        end
)

これは空の結果配列から始まります。暗黙的なループはreduce入力配列を繰り返します。入力配列の各要素は、結果配列にそのまま追加されるか(最初のif分岐)、最後の要素(else分岐)に追加されます。

結果の配列が空の場合、または最後の要素がで始まった[[か終わらない場合、]]現在の要素は最後の要素に追加されるのではなく、結果の配列に追加されます。

テスト:

$ jq . file
[
  "tag1",
  "[[Super",
  "Duppa",
  "Database",
  "Analyst]]",
  "tag2"
]
$ jq -f script file
[
  "tag1",
  "[[Super Duppa Database Analyst]]",
  "tag2"
]

| debug各ステップの後に結果の配列を出力するには、whereステートメントの後に実行します。endifreduce

$ jq -f script file
["DEBUG:",["tag1"]]
["DEBUG:",["tag1","[[Super"]]
["DEBUG:",["tag1","[[Super Duppa"]]
["DEBUG:",["tag1","[[Super Duppa Database"]]
["DEBUG:",["tag1","[[Super Duppa Database Analyst]]"]]
["DEBUG:",["tag1","[[Super Duppa Database Analyst]]","tag2"]]
[
  "tag1",
  "[[Super Duppa Database Analyst]]",
  "tag2"
]

関連情報