Como ordenar linhas em uma ordem específica, como se fosse seu próprio bloco de linhas

0

Eu quero classificar as seguintes linhas de texto para uma ordem específica. Os comandos sort que estou usando estão descartando o espaço e agrupando todas as linhas sem a separação de espaço e colocando-as em ordem alfabética. Cada bloco tem 8 linhas de dados de linha cada.

session:cabSessionID:052FPBP6Q6X2XGERWHBT
cabLoginID:053XCDTF8D4J6PD3BG8P
loginName:jack
userAgent:Mozilla/5.0
sessionStartTime:2018-10-01T01:04:10.899Z
memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:42358792
usedJSHeapSize:36482584

session:cabSessionID:052FPBP6Q6X2XGERWHJE
cabLoginID:053XCDTF8D4J6PD3BG8P
loginName:jack
userAgent:Mozilla/5.0
sessionStartTime:2018-10-01T01:16:41.558Z
memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:177754040
usedJSHeapSize:44842320

memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:45252608
usedJSHeapSize:24555080
session:cabSessionID:055S75T4QC8JYC4Q0456
cabLoginID:053XCDTF8D4J6PD3BG8P
loginName:frank
userAgent:Mozilla/5.0
sessionStartTime:2018-10-23T19:11:11.871Z

Eu quero que o resultado final seja assim:

loginName:jack
cabLoginID:053XCDTF8D4J6PD3BG8P
session:cabSessionID:052FPBP6Q6X2XGERWHBT
userAgent:Mozilla/5.0
sessionStartTime:2018-10-01T01:04:10.899Z
memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:42358792
usedJSHeapSize:36482584

loginName:jack
cabLoginID:053XCDTF8D4J6PD3BG8P
session:cabSessionID:052FPBP6Q6X2XGERWHJE
userAgent:Mozilla/5.0
sessionStartTime:2018-10-01T01:16:41.558Z
memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:177754040
usedJSHeapSize:44842320

loginName:fred
cabLoginID:053XCDTF8D4J6PD3BG8P
session:cabSessionID:055S75T4QC8JYC4Q0456
userAgent:Mozilla/5.0
sessionStartTime:2018-10-23T19:11:11.871Z
memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:45252608
usedJSHeapSize:24555080

    
por Kam 24.10.2018 / 21:55

4 respostas

1

Como você deseja codificar a "classificação", faça o awk compilar os dados para cada bloco em uma matriz associativa e, em seguida, imprima essa matriz na ordem desejada:

scriptfile.awk

BEGIN {
  FS=":"
}

/./ {
  values[$1]=$0
}

/^$/ {
  print values["loginName"]
  print values["cabLoginID"]
  print values["session"]
  print values["userAgent"]
  print values["sessionStartTime"]
  print values["memoryInfo"]
  print values["totalJSHeapSize"]
  print values["usedJSHeapSize"]
  print ""
  delete values
}

END {
  print values["loginName"]
  print values["cabLoginID"]
  print values["session"]
  print values["userAgent"]
  print values["sessionStartTime"]
  print values["memoryInfo"]
  print values["totalJSHeapSize"]
  print values["usedJSHeapSize"]
}

Em seguida, execute:

awk -f scriptfile.awk < input

Como uma alternativa, se você não se importa em qual ordem as linhas de bloco estão, mas quer que elas ainda sejam ordenadas consistentemente, e você tem o GNU awk,

gnuscript.awk

BEGIN {
  FS=":"
  PROCINFO["sorted_in"]="@val_str_asc";
}

/./ {
  values[$1]=$0
}

/^$/ {
  asort(values)
  for (element in values)
    print values[element]
  print ""
  delete values
}

END {
  asort(values)
  for (element in values)
    print values[element]
}

O script acima imprime as linhas de cada bloco em ordem alfabética:

cabLoginID:053XCDTF8D4J6PD3BG8P
loginName:jack
memoryInfo:jsHeapSizeLimit:2217857988
session:cabSessionID:052FPBP6Q6X2XGERWHBT
sessionStartTime:2018-10-01T01:04:10.899Z
totalJSHeapSize:42358792
usedJSHeapSize:36482584
userAgent:Mozilla/5.0
...
    
por 24.10.2018 / 22:17
1

Se você quiser classificar um bloco de linhas da mesma forma várias vezes, não acho que exista uma única linha para isso.

Desde que eu estou preocupado com o awk não pegar todas as strings por causa dos dois pontos no tempo, eu escrevi este pequeno e rápido shell script. Isso realmente os classifica por blocos. A ordem que você tem nos blocos é determinada pelo printf. Atualize isso para atender às suas necessidades.

#!/bin/bash

declare -A arr

(
  while read l; do
    if [[ "" == "${l}" ]]; then
      printf "loginName:%s~cabLoginID:%s~session:%s~userAgent:%s~sessionStartTime:%s~memoryInfo:%s~totalJSHeapSize:%s~usedJSHeapSize:%s~\n" ${arr[loginName]} ${arr[cabLoginID]} ${arr[session]} ${arr[userAgent]} ${arr[sessionStartTime]} ${arr[memoryInfo]} ${arr[totalJSHeapSize]} ${arr[usedJSHeapSize]}
      unset arr
      declare -A arr
      continue
    fi
    k=${l%%:*}
    v=${l#*:}
    arr[${k}]=${v}
  done
  printf "loginName:%s~cabLoginID:%s~session:%s~userAgent:%s~sessionStartTime:%s~memoryInfo:%s~totalJSHeapSize:%s~usedJSHeapSize:%s~\n" ${arr[loginName]} ${arr[cabLoginID]} ${arr[session]} ${arr[userAgent]} ${arr[sessionStartTime]} ${arr[memoryInfo]} ${arr[totalJSHeapSize]} ${arr[usedJSHeapSize]}
) | sort | tr '~' '\n'

exit 0

Espero que isso ajude

    
por 24.10.2018 / 22:33
1

Você pode usar o Perl no modo de parágrafo, com uma ordem de classificação personalizada definida usando um hash, por exemplo,

perl -00 -F'\n' -ne '
our %rank; 
BEGIN {
  %rank = (
    loginName => 1,
    cabLoginID => 2,
    session => 3,
    userAgent => 4,
    sessionStartTime => 5,
    memoryInfo => 6,
    totalJSHeapSize => 7,
    usedJSHeapSize => 8
  );
}

%h = ();
map { ($k,$v) = split(/:/, $_, 2); $h{$k} = $v } @F;
for $k (sort { $rank{$a} <=> $rank{$b} } keys %h) { print "$k:$h{$k}\n" };
print "\n";
' file
    
por 25.10.2018 / 00:20
0

Tente também

awk '
BEGIN   {for (n=split("loginName cabLoginID session userAgent sessionStartTime memoryInfo totalJSHeapSize usedJSHeapSize", T); n; n--) FLSQ[T[n]] = n
        }

        {for (i=1; i<=NF; i++)  {n = split ($i, T, ":")
                                 OUT[FLSQ[T[1]]] = $i
                                }
         for (i=1; i<=NF; i++) $i = OUT[i]
         split ("", OUT)
        }
1
' RS="" ORS="\n\n" FS="\n" OFS="\n"  file
loginName:jack
cabLoginID:053XCDTF8D4J6PD3BG8P
session:cabSessionID:052FPBP6Q6X2XGERWHBT
userAgent:Mozilla/5.0
sessionStartTime:2018-10-01T01:04:10.899Z
memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:42358792
usedJSHeapSize:36482584

.
.
.

Na seção BEGIN , ele define a sequência de campo na saída de cada registro, atribuindo a cada rótulo de campo um número crescente. Ao operar em registros de várias linhas, tendo dividido o rótulo na matriz T , ele preenche a matriz OUT com o campo inteiro, indexado pelo número da etiqueta. Última ação antes de imprimir o registro é reconstruir todo o $ 0 (= registro). Todos os separadores de campo e registro devem ser adaptados ao layout de registro de múltiplas linhas.

    
por 25.10.2018 / 00:38

Tags