使用jq递归提取对象值和父键名

时间:2018-02-05 18:45:09

标签: json npm jq

我需要解析npm ls --global --json命令的输出,以便按以下格式获取所有已安装的npm包的列表:

$package;$version;js;$resolved

其中:

  • $package是包含每个dependencies对象的包名称的密钥。
  • $version是从每个包中获取的version
  • js只是一个文字字符串
  • $resolved是从每个包中获取的resolved

我已经得到了这个命令语法和输出:

$ jq --raw-output 'select( has("dependencies") ) .dependencies[] | . as $d | "parentkey" + ";" + $d.version + ";js;" + $d.resolved'`
parentkey;5.5.1;js;
parentkey;1.1.3;js;https://registry.npmjs.org/yaml-table/-/yaml-table-1.1.3.tgz

我特别遇到困难的部分如下:

  • 如何获取我在包含该包名称的.dependencies中迭代的键名值。到目前为止,我正在查看该对象本身的内容。

  • 如何通过ALL依赖项对象进行递归?目前我只查看根.dependencies对象中的顶级记录。我发现了..递归,但我不太清楚如何在这里应用它。

根据以下示例数据,我尝试达到以下输出结果:

npm;5.5.1;js;
JSONStream;1.3.1;js;https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz
jsonparse;1.3.1;js;https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz
through;2.3.8;js;https://registry.npmjs.org/through/-/through-2.3.8.tgz
yaml-table;1.1.3;js;https://registry.npmjs.org/yaml-table/-/yaml-table-1.1.3.tgz
js-yaml;3.4.6;js;https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz
argparse;1.0.9;js;https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz

我用于上述示例的一些(大大减少的)样本输出npm ls --global --json如下:

{
  "dependencies": {
    "npm": {
      "version": "5.5.1",
      "dependencies": {
        "JSONStream": {
          "version": "1.3.1",
          "from": "JSONStream@~1.3.1",
          "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz",
          "dependencies": {
            "jsonparse": {
              "version": "1.3.1",
              "from": "jsonparse@^1.2.0",
              "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz"
            },
            "through": {
              "version": "2.3.8",
              "from": "through@>=2.2.7 <3",
              "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
            }
          }
        }
      }
    },
    "yaml-table": {
      "version": "1.1.3",
      "from": "yaml-table@latest",
      "resolved": "https://registry.npmjs.org/yaml-table/-/yaml-table-1.1.3.tgz",
      "dependencies": {
        "js-yaml": {
          "version": "3.4.6",
          "from": "js-yaml@3.4.6",
          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz",
          "dependencies": {
            "argparse": {
              "version": "1.0.9",
              "from": "argparse@>=1.0.2 <2.0.0",
              "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz"
            }
          }
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:2)

通过使用..,它将递归json树中的所有值。因此,您需要通过具有您期望的结构的对象来过滤掉这些内容。在这种情况下,具有有效dependencies对象的东西。找到对象后,可以提取所需的值。

jq -r '.. | .dependencies? | objects
    | to_entries[] | [.key, .value.version, "js", .value.resolved] | join(";")' input.json

产生结果:

npm;5.5.1;js;
yaml-table;1.1.3;js;https://registry.npmjs.org/yaml-table/-/yaml-table-1.1.3.tgz
JSONStream;1.3.1;js;https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz
jsonparse;1.3.1;js;https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz
through;2.3.8;js;https://registry.npmjs.org/through/-/through-2.3.8.tgz
js-yaml;3.4.6;js;https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.6.tgz
argparse;1.0.9;js;https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz