Extrai campos de uma linha em variáveis do shell

1

Eu tenho algumas centenas de linhas, como abaixo, em connRefused.log : -

        2015-12-12 00:12:10,227 ERROR [Testing-KeepAlive-01] c.v.v.v.Connection [Connection.java : 001] failed to bind to {name=TestGW,direction=BOTH_WAY,username=espada,password=whatever,binds=1,keepAliveInterval=60000,params={Payload=0, useEXP=1},thisOne={id=1001,name=TestGw,ip=192.168.0.1,port=88}}: Connection refused

e abaixo é parte do meu script (simplificado) para ler o connRefused.log no array

IFS=$'\n' read -d '' -r -a lines < /path/log/connRefused.log
for xx in "${lines[@]}"
  do
    ??? # what to do here?
    echo $Date
    echo $ID
    echo $Name
    echo $IP
    echo $Port
  done

Como posso obter os dados de que preciso da linha acima para armazená-los na variável Data, ID, Nome, IP, Porta?

thisOne={id=1001,name=TestGw,ip=192.168.0.1,port=88} .

e para o $ Date, eu só preciso da parte do tempo.

    
por Asif 16.12.2015 / 04:33

1 resposta

1

Você não precisa usar uma matriz. Como os dados de entrada parecem ser muito regulares, eu converteria os dados de entrada em instruções de atribuição de shell, depois os leria no shell e avaliaria. Assim:

#!/bin/sh

sed '
    s/^[-0-9]*  */date=/
    s/,.*thisOne={/ /
    s/}.*//
    s/,/ /g
' "$@" |
while read line
do
    eval $line
    echo date=$date
    echo id=$id
    echo name=$name
    echo ip=$ip
    echo port=$port
done

O comando sed converte a linha de entrada para isso:

date=00:12:10 id=1001 name=TestGw ip=192.168.0.1 port=88

O loop while lê uma dessas linhas por vez e eval $line faz com que a linha seja executada no shell, o que resulta nas variáveis sendo definidas para os valores fornecidos.

O script processará os nomes dos arquivos a partir da linha de comando OU da entrada padrão (observe o "$@" no final do comando sed ).

O comando sed converte a linha em instruções de designação de shell por meio de uma série de comandos s (substitute):

  1. Substitua, apenas no início da linha ( ^ ), qualquer sequência de traços e dígitos ( [-0-9]* ), seguida por um ou mais espaços ( * ) com date= :

    s/^[-0-9]*  */date=/
    
  2. Substitua uma vírgula seguida por qualquer caractere ( .* ) seguido por thisOne= com um espaço:

    s/,.*thisOne={/ /
    
  3. Exclua uma chave de fechamento ( } ) seguida por quaisquer outros caracteres ( .* ) para o final (implícito) da linha:

    s/}.*//
    
  4. Substitua todas as vírgulas ( , ) por espaços:

    s/,/ /g
    

No script de exemplo, recomendo que você exclua temporariamente o canal | no final do arquivo e execute somente a parte do comando sed do script para que você possa experimentar e ver como ele funciona.

    
por 16.12.2015 / 07:20