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"
]

관련 정보