我需要从 JSON 文件中获取与“版本”键关联的值jq
,grep
无论前者是否未安装。我正在使用 Zsh 5.7.1。
JSON文件看起来像这样;
{
"version": "1.7.0+01e7dgc6",
"date": "2020-04-06",
}
因此,预期的结果是:
1.7.0+01e7dgc6
这是我的带有条件测试的脚本,它提供了一个正则表达式,该正则表达式又被传递给匿名函数的位置参数:
#!/usr/bin/env zsh
# Fetch silently JSON latest numeroted version with `jq` if installed; fallback to `grep` otherwise.
set -x
if dpkg -s 'jq' | grep -qF 'install ok installed'; then
print "using jq"
API="jq -r '.master.version'"
else
print "falling back to grep"
API="grep -Po '(?<="version": "\)\[\^"]*'"
fi
function {
local JSON='path/to/URL/index.json'
curl -fsSL "$JSON" | $@
} ${API}
上面的脚本返回以下错误(在调试模式下):
+(anon):2> curl -fsSL path/to/the/URL/index.json
+(anon):2> 'jq -r '\''.master.version'\'
(anon):2: command not found: 'jq -r '.master.version'
curl: (23) Failed writing body (0 != 9320)
您可以看到该命令未找到,因为正则表达式已被 espace 序列字符解释(即'jq -r '\''.master.version'\')。这就是为什么我需要原始字符串将正则表达式正确解析为位置参数的原因。
当测试失败时,同样的错误肯定会上升:
falling back to grep
+dpkg.zsh:9> API='grep -Po '\''(?<=version: )[^]*'\'
...
+(anon):2> 'grep -Po '\''(?<=version: )[^]*'\'
(anon):2: command not found: grep -Po '(?<=version: )[^]*'
curl: (23) Failed writing body (0 != 9320)
How can I correctly parse the regex by NOT escaping characters like the single quote (i.e. '
) as there is no such thing as a raw string mechanism within Z Shell?
Is it possible with parameter expansion? I tried those in vain:
- P flag (i.e. espace sequence replacement)
- g:c (process escape sequence with concatenation option)
- e flag (performs single word shell expansion)
or with globbing qualifiers? or perhaps with sub-string modifiers?
EDIT: You made my day. I'm grateful to both user1934428 and chepner for your kindness.