【问题标题】:Unable to extract specific value of json file using sed in shell script无法在 shell 脚本中使用 sed 提取 json 文件的特定值
【发布时间】:2019-10-05 22:49:38
【问题描述】:

我正在使用 sed 命令提取执行 curl 后从输出中获得的值。下面是我的 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

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

在这方面需要帮助。

【问题讨论】:

  • 删除了 -i 命令。

标签: json shell sed


【解决方案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"

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 管道可以简化为单个sed 脚本。您通常可以通过更改您的sed 脚本来摆脱head,以便在打印某些内容后立即退出。但我没有更详细地研究这个;正如竞争答案所暗示的那样,您真的不想为此使用sed
    【解决方案3】:

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

    你可以试试这个 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":以及返回文本中的逗号。

    【讨论】:

      猜你喜欢
      • 2019-10-15
      • 2022-11-14
      • 2020-06-18
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      • 2018-07-05
      • 2021-01-16
      相关资源
      最近更新 更多