Como dividir cada valor em linhas separadas e classificadas?

0

Estou tentando converter o arquivo de texto, mas parece ser um pouco difícil para mim organizá-lo como o que pretendo.

O arquivo se parece com o abaixo.

(0,{35=9000.0, 36=9000.0, 33=9000.0, 34=9000.0})

Eu quero organizá-los da seguinte forma

0 33 9000.0
0 34 9000.0
0 35 9000.0
0 36 9000.0

Já que sou novo em shell, preciso da sua ajuda para resolver meu problema. Eu quero que eles sejam classificados por valores dentro de {} .

Obrigado.

    
por sclee1 10.08.2017 / 21:09

4 respostas

2

Aqui solução em Perl:

cat b.txt 
(0,1,{35=9000.0, 36=9000.0, 33=9000.0, 34=9000.0})

perl -lne '$_=~/^\(([\d\,\.]+)\s*\{(.*)\}\)$/; @first=split /[,\s]/, $1; @second=split /,\s/, $2; map{($k, $v) = split "=", $_; $h{$k}=$v} @second; foreach $k (sort keys(%h)) { print join(" ", @first), " $k ",$h{$k}; }' b.txt
0 1 33 9000.0
0 1 34 9000.0
0 1 35 9000.0
0 1 36 9000.0

(É claro que este programa Perl será muito mais fácil de ler se usar mais que uma linha e se eu souber como dar nomes de significado a variáveis)

    
por 10.08.2017 / 22:18
2

Aqui está uma solução awk :

sed 's/=/ /' <(awk -F"[ ,)(}{]" '{
                  for (i=4;i<NF;i+=2){printf"%s %s\n",$2,$i|"sort -nk2,3"}}
              ' infile.txt)

Dando saída:

0 33 9000.0
0 34 9000.0
0 35 9000.0
0 36 9000.0

se suas entradas forem como abaixo (como implementado na resposta de @Fedor):

(0,1,{35=9000.0, 36=9000.0, 33=9000.0, 34=9000.0})

Então o comando seria:

sed 's/=/ /' <(awk -F"[ ,)(}{]" '{
                  for (i=5;i<NF;i+=2) {printf "%s %s %s\n",$2, $3,$i|"sort -nk2,3"}}
              ' infile.txt)

E a saída:

0 1 33 9000.0
0 1 34 9000.0
0 1 35 9000.0
0 1 36 9000.0
    
por 10.08.2017 / 22:33
1
Solução do

GNU awk :

awk -F'[,=]' '{ gsub(/[({}) ]/,"",$0); for(i=2;i<NF;i+=2) a[$i]=$(i+1); 
                asorti(a,b); for(k in a) print $1,k,a[k] }' file
  • -F'[,=]' - separador de campos

  • gsub(/[({}) ]/,"",$0) - removendo caracteres desnecessários

  • for(i=2;i<NF;i+=2) a[$i]=$(i+1) - coletando pares de valores na matriz a

  • asorti(a,b) - classifique a matriz a por chaves

A saída:

0 33 9000.0
0 34 9000.0
0 35 9000.0
0 36 9000.0
    
por 10.08.2017 / 22:43
1
  1. Para cada linha de entrada, $n < = valor decimal antes da vírgula principal.
  2. hash %h cujas chaves são o número à esquerda de = e os valores à direita.
  3. então, numericamente, classifique as chaves e imprima a $n , key, corresp. valor.
  4. $, = OFS < = $" = Separador de lista de saída, que é espaço por padrão.
perl -lne '$,=$";
   ($n, %h) = ( /^\((\d+),/, /(\d+)=([^,}]+)/g );
   print $n, $_, $h{$_} for sort { $a <=> $b } keys %h;
' yourfile

Resultados:

0 33 9000.0
0 34 9000.0
0 35 9000.0
0 36 9000.0
    
por 11.08.2017 / 10:12