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

时间:2019-05-19 08:45:22

标签: json shell sed

我正在使用sed命令来提取卷曲后从输出中获取的值。下面是我的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
   }
 }
 ]
}

我上面发布的sed命令必须正常工作,因为它正在处理另一个curl命令。

id值多次出现,但我希望第一个ID的值存储在id变量"id": 1234332

但是作为输出我什么也没得到。

需要帮助。

3 个答案:

答案 0 :(得分:1)

  1. 除非您想扩展带引号的字符串中的任何内容,否则不要使用双引号而不是单引号
  2. 使用解析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"

答案 1 :(得分:1)

我更正了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

答案 2 :(得分:0)

双反斜杠与文字反斜杠匹配,这就是为什么您的代码不起作用的原因。

您可以尝试以下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或mor数字和逗号,以及sed 's/"id": //' | sed 's/,//'将从返回文本中删除"id":和逗号。