Linux Extrai o campo de texto correspondente do arquivo

1

Eu tenho um arquivo que tem muitas linhas do formato:

bc("STG1/Phone") = {type=bana_pub; cbb=12.354; abb=0.0}'

Estou procurando extrair cbb=12.354; . Atualmente, estou fazendo o seguinte:

cat input_file.txt | grep cbb | awk -F " " '{ print $4 }''

O problema é que minha abordagem é localização específica, ou seja, assume que é sempre o 4º campo. Como faço para extrair o texto do formulário cbb= sabendo que o = poderia ser qualquer comprimento e o ponto-e-vírgula ; é opcional. A única garantia que tenho é que o termo cbb=12.354; será cercado por espaços em branco se isso ajudar. O arquivo no futuro pode estar no formato:

bc("STG1/Phone") = {type=bana_pub; cbb=12.354; abb=0.0}
bc("STG1/Phone") = {type=bana_pub;  abb=0.0; cbb=12.354}

Meu instinto me diz que regex é provavelmente o caminho a seguir, mas eu geralmente tento evitá-lo se puder, pois prefiro ferramentas simples de correspondência (que eu entendo melhor).

Obrigado por antecipar sua ajuda.

    
por fswings 27.10.2017 / 14:54

4 respostas

2

Solução:

grep -Eo 'cbb=[^;}]+'

Vamos testá-lo:

$ grep -Eo 'cbb=[^;}]+' <<<'bc("STG1/Phone") = {type=bana_pub; cbb=12.354; abb=0.0}''
$ cbb=12.354

Explicação:

Quando você usa ... | grep cbb | ... , está usando o regex básico. O regex avançado não é tão complicado.

A opção -E é para regex avançada, útil para não escapar de alguns metacaracteres. -o é para imprimir apenas o que o grep corresponde em vez da linha inteira.

O regex cbb=[^;}]+ seria o mesmo para qualquer outro cmd, não apenas grep.

cbb= é uma string fixa, não há meta-caractere lá ( c seguido por b etc)

[^;}]+ colchetes delimitam um conjunto de caracteres em uma única posição. Um acento circunflexo no início significa conjunto de caracteres negado. O sinal de mais significa um ou mais caracteres. Dessa forma, ele corresponderá a qualquer caractere, pelo menos um, até encontrar um ; ou }

Aqui está um bom link para saber mais sobre regexes: link

    
por 28.10.2017 / 02:02
2

Isso funciona e é independente da posição:

grep cbb input_file.txt | awk -F "cbb=" '{ print $2 }'| awk -F ";" '{print "cbb=" $1}'

Primeiro, seleciona apenas linhas contendo cbb , depois usa a string cbb= como separador e finalmente usa ; como separador de campo adicionando a string cbb = ao resultado final.

    
por 27.10.2017 / 15:19
0

Você também pode usar sed (já que sed é chamado apenas uma vez, deve ser mais rápido)

sed -n 's/^.*\(cbb=[0-9\.]*\).*$//p' sample.txt

Em que sample.txt é seu arquivo de entrada. Verifique apenas o numérico ([0-9.]) Para resolver um possível problema com ponto e vírgula opcional.

    
por 28.10.2017 / 02:21
0

Nesse caso, grep é a ferramenta certa para o trabalho. No entanto, pensei em adicionar:

  • Perl

    perl -lane 'print $1 if /(cbb=[^;}]+)/' input_file.txt
    
  • AWK

    awk 'match($0,/cbb=[^;}]+/,m) {print m[0]}' input_file.txt
    
  • Sed

    sed -rn 's/.*(cbb=[^;}]+).*//p' input_file.txt
    

Créditos para Paulo por entender o que o OP quis dizer com:

after the = it could be any length and the semi-colon ; is optional. The only guarantee I have is that the term cbb=12.354; will be surrounded by whitespace

    
por 02.11.2017 / 11:24