给出命令:
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
and$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
,$ed
正如meuh已经提到的。它们是在数组表达式内定义的,因此作用域也在该表达式内。当您调用 时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
)
这从一个空结果数组开始。 then的隐式循环reduce
迭代输入数组。输入数组的每个元素要么按原样添加到结果数组(第一个if
分支),要么附加到其最后一个元素(else
分支)。
如果结果数组为空或者其最后一个元素不以 开头[[
或以 结尾]]
,则当前元素将添加到结果数组中,而不是附加到其最后一个元素。
测试:
$ jq . file
[
"tag1",
"[[Super",
"Duppa",
"Database",
"Analyst]]",
"tag2"
]
$ jq -f script file
[
"tag1",
"[[Super Duppa Database Analyst]]",
"tag2"
]
在其中语句的| debug
后面运行 with以在每个步骤后输出结果数组:end
if
reduce
$ 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"
]