Formata dados como uma tabela no bash

2

Eu tenho uma matriz de dados JSON sendo impressos no terminal (OS X) e quero que as propriedades sejam exibidas em uma tabela no terminal.

Exemplo de consulta:

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")) ]'

Dito de outra forma: Eu quero pegar a estrutura de dados resultante (array de objetos que contém propriedades 'endereços', 'grupos', 'dns', 'nome') e empurrar cada objeto para uma linha de uma tabela, dentro o terminal / bash.

Eu não me importo de deixar os dados serem EOF-ed antes que a tabela comece a desenhar.

Exemplo de 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"
  }
]
    
por Henrik 26.08.2013 / 11:42

2 respostas

0

Como o OS X vem com o Ruby:

sudo gem install json
sudo gem install table_print

Para fins de demonstração, salvei sua string JSON no arquivo input , mas você pode canalizá-la para ruby também:

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

Esta saída:

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
    
por 26.08.2013 / 14:04
0

Resposta legal @slhck!

Veja alguns outros exemplos:

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 verificará as matrizes agora:

#!/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 produz o número de colunas que o grupo atual tem.)

    
por 26.08.2013 / 22:31

Tags