无法在shell脚本中使用sed提取json文件的特定值

jxct1oxe  于 2022-11-16  发布在  Shell
关注(0)|答案(3)|浏览(149)

我使用sed命令来提取一个值,这个值是我在执行curl操作后从输出中得到的。

#!/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
   }
 }
 ]
}

我在上面发布的sed命令必须像它对另一个curl命令一样工作。
id值出现多次,但我希望将第一个ID值存储在id变量中,即"id": 1234332
但作为输出,我什么也得不到。
需要帮助。

tkclm6bt

tkclm6bt1#

我更正了sed命令,它工作了。
双反斜杠\\在转义命令的地方,所以我把它改为单反斜杠\下面是修改后的shell脚本。

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
lfapxunr

lfapxunr2#

1.不要使用双引号而不是单引号,除非您希望扩展带引号的字符串中的任何内容,
1.使用jq解析JSON值,sed是一个面向行的工具,不能解析JSON语法。
例如:

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')
echo "$id"
zysjyyx4

zysjyyx43#

双反斜杠与文字反斜杠匹配,这就是代码无法工作的原因。
您可以尝试以下grep:

id=$(grep -o -m 1 '"id": [0-9]\{1,\},' <<< "$release" | sed 's/"id": //' | sed 's/,//')

-m 1将仅获取第一个匹配项(选中Grep only the first match and stop),-o将获取正则表达式匹配文本-"id": + 1或莫尔个数字和逗号,sed 's/"id": //' | sed 's/,//'将从返回文本中删除"id":和逗号。

相关问题