在 Bash 中将数据格式化为表格

在 Bash 中将数据格式化为表格

我有一个 JSON 数据数组被打印到终端(OS X),并且我希望它的属性显示在终端的表格中。

示例查询:

aws ec2 describe-instances 
  | jq '[ .[] | .[] | .Instances[] as $ins
  | { groups: $ins.SecurityGroups[].GroupName,
    addresses: [ $ins.PrivateIpAddress, $ins.PublicIpAddress ],
    dns: $ins.PrivateDnsName,
    name: ($ins.Tags[] as $ts | $ts.Key == "Name" | $ts.Value ) }
  | select(.name | contains("prod")) ]'

换句话说:我想要获取生成的数据结构(包含属性“地址”、“组”、“dns”、“名称”)并将每个对象推入终端/bash 内的表格的一行中。

我不介意在表格开始绘制之前让数据以 EOF 结尾。

示例 JSON:

[
  {
    "name": "prod-clusterX-01",
    "dns": "ip-10-34-XX-XX.eu-west-1.compute.internal",
    "addresses": [
      "10.34.XX.XX",
      "54.246.XX.XX"
    ],
    "groups": "prod-clusterX"
  },
  {
    "name": "prod-revproxy-a",
    "dns": "ip-10-0-XX-XX.eu-west-1.compute.internal",
    "addresses": [
      "10.0.XX.XX",
      "54.229.XX.XX"
    ],
    "groups": "prod-revproxy"
  }
]

答案1

由于 OS X 附带 Ruby:

sudo gem install json
sudo gem install table_print

出于演示目的,我已将您的 JSON 字符串保存到文件input,但您也可以将其通过管道传输到ruby

ruby -e 'require "rubygems"; require "json"; require "table_print";
d = JSON.parse(ARGF.read);
d = d.map { |row| row["addresses"] = row["addresses"].join(", "); row }; 
tp.set :max_width, 120;
tp d' < input

输出:

NAME             | DNS                                       | GROUPS        | ADDRESSES
--------------------------------------------------------------------------------------------------------
prod-clusterX-01 | ip-10-34-XX-XX.eu-west-1.compute.internal | prod-clusterX | 10.34.XX.XX, 54.246.XX.XX
prod-revproxy-a  | ip-10-0-XX-XX.eu-west-1.compute.internal  | prod-revproxy | 10.0.XX.XX, 54.229.XX.XX

答案2

很好的回答@slhck!

以下是其他一些示例:

aws ec2 describe-instances | jq '[ .[] | .[] | .Instances[] as $ins
  | select(.Platform == null)
  | { instance_type: $ins.InstanceType,
      name: ($ins.Tags[] as $ts | select($ts.Key == "Name") | $ts.Value ),
      security_groups: $ins.SecurityGroups[].GroupName,
      launched: $ins.LaunchTime } ]' | ./to-table.rb

to-table.rb现在将检查数组本身:

#!/usr/bin/env ruby

require "json"
require "table_print"

def join_arrays row
  row.keys.each do |key|
    row[key] = row[key].join(', ') if row[key].respond_to? :join
  end
end

d = JSON.parse(ARGF.read).each { |row| join_arrays row }
w = `/usr/bin/env tput cols`.to_i
tp.set :max_width, w
tp d

(PS:tput cols得出列数当前 bash 具有的功能。)

相关内容