Shell脚本中使用sed提取JSON首个id值失败求助
解决sed提取GitHub Release JSON中id值无输出的问题
我来帮你搞定这个问题!你的sed命令没输出,主要是因为正则表达式没匹配到目标行,咱们一步步来分析和解决:
问题根源分析
先看你写的sed表达式:
sed -n -e 's/"id":\\ \\([0-9]\\+\\),/\\1/p'
这里有几个关键问题:
- 你用
\\ \\试图匹配空格,但实际JSON里"id"后面只有一个空格,多余的转义反而让匹配逻辑混乱; - 目标行的
"id": 1234332后面没有逗号,但你的表达式强制要求匹配逗号,直接导致完全匹配失败; - 没有考虑JSON行首的缩进空格,进一步降低了匹配概率。
修复后的sed命令
把提取id的行替换成下面的命令,就能正确捕获到顶层的id值:
id=$(echo "$release" | sed -n 's/^ *"id": *\([0-9]\+\),*$/\1/p' | head -n 1)
我来拆解一下这个正则的逻辑:
^ *:匹配行首任意数量的空格,适配JSON的缩进格式;"id": *:匹配"id":以及后面任意数量的空格(兼容不同的格式化风格);\([0-9]\+\):捕获连续的数字序列,也就是我们需要的id值;,*$:匹配行尾可选的逗号,兼容JSON中某些字段后面带逗号的情况;\1:输出捕获到的数字内容。
更稳妥的替代方案:用jq处理JSON
其实用sed处理结构化的JSON是很脆弱的——如果JSON的格式稍有变化(比如空格调整、换行位置改变),sed命令就可能失效。更专业的做法是用专门的JSON处理工具jq,一行就能精准提取顶层id:
# 直接整合curl和jq,无需额外的echo和sed id=$(curl -H "Authorization:token xxxxxxxxxxxxxxxxxxxxxx" -H "Content-Type: application/json" https://api.github.com/repos/octocat/Hello-World/releases/tags/v1.0.0 | jq -r '.id')
-r参数:让jq输出原始字符串(不带引号);.id:直接访问JSON顶层的id字段,完全不会误抓嵌套在author或assets里的其他id值。
你的原脚本与返回JSON
原Shell脚本
#!/bin/bash release=$(curl -H "Authorization:token xxxxxxxxxxxxxxxxxxxxxx" -H "Content-Type: application/json" https://api.github.com/repos/octocat/Hello-World/releases/tags/v1.0.0) id=$(echo "$release" |sed -n -e 's/"id":\\ \\([0-9]\\+\\),/\\1/p' | head -n 1 | sed 's/[[:blank:]]//g') echo $id
curl返回的JSON
{ "url": "https://api.github.com/repos/octocat/Hello-World/releases/1", "html_url": "https://github.com/octocat/Hello-World/releases/v1.0.0", "assets_url": "https://api.github.com/repos/octocat/Hello- World/releases/1/assets", "upload_url": "https://uploads.github.com/repos/octocat/Hello- World/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/octocat/Hello- World/tarball/v1.0.0", "zipball_url": "https://api.github.com/repos/octocat/Hello- World/zipball/v1.0.0", "id": 1234332, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "v1.0.0", "target_commitish": "master", "name": "v1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1353322, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner} {/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "received_events_url": "https://api.github.com/users/octocat/received_events", "type": "User", "site_admin": false }, "assets": [ { "url": "https://api.github.com/repos/octocat/Hello- World/releases/assets/1", "browser_download_url": "https://github.com/octocat/Hello- World/releases/download/v1.0.0/example.zip", "id": 56432211, "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", "name": "example.zip", "label": "short description", "state": "uploaded", "content_type": "application/zip", "size": 1024, "download_count": 42, "created_at": "2013-02-27T19:35:32Z", "updated_at": "2013-02-27T19:35:32Z", "uploader": { "login": "octocat", "id": 5663322, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner} {/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "received_events_url": "https://api.github.com/users/octocat/received_events", "type": "User", "site_admin": false } } ] }
内容的提问来源于stack exchange,提问作者Sumith08
相关产品推荐
相关产品推荐

