如何将自定义Shell函数传入jq的select函数?报错解决
问题分析与解决方案
核心错误点
- jq无法调用shell函数:jq有独立的运行环境和语法体系,不能直接在jq表达式中调用自定义的shell函数
checkName。 - 变量传递错误:
$1是shell的位置参数,不能直接嵌入jq表达式,必须通过--arg参数将shell变量传递给jq使用。 - 输入处理逻辑混乱:原代码的jq管道未正确关联输入流,且你的
bookmark.json属于JSON Lines格式(多个独立JSON对象),同时原jq的查询路径.roots.bookmark_bar.children[]与实际输入的JSON结构不匹配。
修正后的代码
直接使用jq内置的字符串匹配功能即可实现需求,无需依赖shell函数:
方案1:忽略大小写匹配(推荐)
function fetchLog(){ jq -r --arg keyword "$1" 'inputs | select(.name | test($keyword; "i")) | {name, url}' bookmark.json }
方案2:区分大小写的子串匹配
function fetchLog(){ jq -r --arg keyword "$1" 'inputs | select(.name | contains($keyword)) | {name, url}' bookmark.json }
代码说明
--arg keyword "$1":将shell函数的第一个参数(查询关键词)传递给jq,在jq中用$keyword引用该变量。inputs:遍历输入文件中的每个独立JSON对象,适配你当前的JSON Lines格式。select(.name | test($keyword; "i")):通过正则匹配判断name字段是否包含关键词,"i"标记实现忽略大小写;若使用contains($keyword)则是精确区分大小写的子串匹配。{name, url}:输出仅保留name和url字段的JSON对象。
补充:若JSON包含.roots.bookmark_bar.children层级
如果你贴出的bookmark.json只是children数组内的元素,实际完整JSON包含上层结构,可调整代码为:
function fetchLog(){ jq -r --arg keyword "$1" '.roots.bookmark_bar.children[] | select(.name | test($keyword; "i")) | {name, url}' bookmark.json }
测试效果
执行fetchLog networking后,会输出匹配的对象:
{ "name": "Networking", "url": "https://www.youtube.com/watch?v=AhOU2eOpmX0&list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi&index=7" }
内容的提问来源于stack exchange,提问作者Tmak
相关产品推荐
相关产品推荐

