Converter / proc / cpuinfo para um JSON no bash do linux

4

Gostaria de converter toda a entrada de um cat /proc/cpuinfo em um JSON de "key" : "value" .

Isso é possível? Eu tentei explodir a string usando \n na esperança de que eu pudesse pegar cada linha e então eu poderia explodir cada linha usando : .

Mas o caractere de nova linha parece produzir um array inconsistente.

    
por Kousha 06.06.2015 / 00:04

3 respostas

3

Bem, para uma abordagem simples, você poderia fazer:

sed 's/\(.*\)\t:\(.*\)/"" : ""/' /proc/cpuinfo 

Isso corresponderá a tudo até uma guia seguida de dois pontos e salvará como , depois de tudo após os dois pontos e salvará como . A substituição coloca aspas em torno deles.

Isso, no entanto, resulta em casos como estes:

"fpu    " : " yes"
power management:

Os itens com espaços em branco extras antes da guia têm seus espaços em branco incluídos e os vazios são ignorados. Esta versão do Perl lida com os corretamente:

perl -F: -alpe 's/.*/"$F[0]" : "$F[1]"/' /proc/cpuinfo 

Isso dividirá a linha em : na matriz @F ( -F define o caractere para dividir e -a ativa a divisão automática em @F ) e imprime cada lado citado. Ele será quebrado se você tiver mais de um : em uma linha, mas não acho que isso acontecerá em /proc/cpuinfo . No entanto, também imprime todas as linhas em branco no arquivo. Para evitar isso, canalize-o em grep first:

grep . /proc/cpuinfo | perl -F: -alpe 's/.*/"$F[0]" : "$F[1]"/' /proc/cpuinfo 

Ou, imprima apenas se uma linha contiver : :

perl -F: -alne 's/.*:.*/"$F[0]" : "$F[1]"/ && print' /proc/cpuinfo 
    
por 06.06.2015 / 01:02
3
sed -n '/./s/ *\(\( *[^:[:blank:]]\)*\)[^:]*\(:*\)/""/gp' /proc/cpuinfo

... funciona em sed . Com os atalhos do GNU, você pode escrever praticamente a mesma declaração como:

sed -En 's/ *(( ?[^ :\t])+)\s*(:?)/""/gp' /proc/cpuinfo

Isso é um pouco chato (porque eu poderia fazer melhor com alguns pressionamentos de tecla e jw ) , mas eu estava brincando com sed e ...

set '   ' $'\\n' $'\n' '      '
sed -En "\$c$2$1}$2]${3}1ccpus$1=$1[$2$1{$3/^$/c$2$1},$2$1{
        s/ *(( ?[^ :\t])+)(\s*:\s*)?\s*/\"\"/g
        s/\"(([yn]).s?|([0-9]+))\"$/falsetrue/
        s/falsey|ntrue|([0-9])f\w+$//
        /^.flags./{
                s/\s*:\s*/$1=$1[/;h
                s/.*\t.//;x;s/(.*\t.).*//;x
                s/ /\",$2\"/g
                s/^/pr -to24 -a4 <<''$2/e;H;x
                s/$/$2$1$1]/
};      s/.*/$1$4&,/p" /proc/cpuinfo

Eu acho que a saída é algo próximo de válido. Eu tirei uma foto porque nunca consigo fazer as guias se alinharem na janela do navegador como na janela do terminal.

A maioria das tabulações são trapachadas de qualquer maneira - pr faz a formatação flags através do comando GNU sed e , e para o resto eu preservo a maior parte da saída originalmente formatada como Eu devo. Por exemplo, porque eu tive que inserir dois caracteres - as aspas duplas - em torno dos membros do nome, quando eu também insiro a tabulação principal, eu faço uma aba real seguida por seis espaços em uma tentativa grosseira de manter a posição atual de parada de tabulação.

Aqui está o primeiro hash:

    
por 06.06.2015 / 17:37
2

Minha versão:

#!/usr/bin/env perl

use strict;
use warnings;

use JSON;
use Storable qw(dclone);

my ( %h, @cpu );

while (<>) {
    chomp;

    if (m/^$/o) {
        push @cpu, dclone( \%h );
        undef %h;
        next;
    }

    my ( $k, $v ) = split /\s*:\s*/, $_, 2;

    if ( !defined $v or $v eq '' ) { $h{$k} = undef }
    elsif ( $k eq 'flags' )        { $h{$k} = [ split /\s/, $v ] }
    elsif ( $v =~ /^\d+$/o )       { $h{$k} = int ($v) }
    elsif ( $v eq 'yes' )          { $h{$k} =  }
    elsif ( $v eq 'no' )           { $h{$k} = 
#!/usr/bin/env perl

use strict;
use warnings;

use JSON;
use Storable qw(dclone);

my ( %h, @cpu );

while (<>) {
    chomp;

    if (m/^$/o) {
        push @cpu, dclone( \%h );
        undef %h;
        next;
    }

    my ( $k, $v ) = split /\s*:\s*/, $_, 2;

    if ( !defined $v or $v eq '' ) { $h{$k} = undef }
    elsif ( $k eq 'flags' )        { $h{$k} = [ split /\s/, $v ] }
    elsif ( $v =~ /^\d+$/o )       { $h{$k} = int ($v) }
    elsif ( $v eq 'yes' )          { $h{$k} =  }
    elsif ( $v eq 'no' )           { $h{$k} = %pre% }
    else                           { $h{$k} = $v }
}

print JSON->new->pretty->encode( \@cpu );
} else { $h{$k} = $v } } print JSON->new->pretty->encode( \@cpu );

Isso pressupõe que há uma linha em branco entre cada definição de CPU.

    
por 06.06.2015 / 06:47