Encontre o padrão de string no arquivo/entrada, pesquisa dependente do contexto (não como grep)

Encontre o padrão de string no arquivo/entrada, pesquisa dependente do contexto (não como grep)

Existe algum utilitário disponível para localizar texto, como em grep(linux) ou findstr(dos), mas para começar a procurar somente depois que outro texto/padrão for encontrado?

É como tentar encontrar determinado texto/padrão em um arquivo, mas apenas aqueles que estão dentro de uma seção específica do arquivo. Apenas 'o arquivo' no meu caso é uma saída de outro programa e a quantidade de linhas geradas é demais para gravar em um arquivo e analisá-lo lá.

exemplo:

section ONE
  text_a
  text_b
  text_c
section TWO
  text_b
  text_c
section THREE
  . . .

descubra se existe algum "text_c" apenas na seção DOIS.

Tentei ler grepas opções de mas não parece ter essa capacidade. Espera-se que isso também minimize a quantidade de comparações de strings, uma vez que "text_c" é muito mais longo que os nomes das seções.

Responder1

Vamos considerar este arquivo de teste:

$ cat file
section ONE
  text_a
  text_b
  text_c  <-ignore this
section TWO
  text_b
  text_c  <-keep this
section THREE
  text_a
  text_b
  text_c  <-ignore this

Para selecionar qualquer linha que contenha text_cisso section TWO:

$ awk '/^section/{f=0} /^section TWO/{f=1} f && /text_c/' file
  text_c  <-keep this

Se a entrada for gerada não de um arquivo, mas de command, use:

command | awk '/^section/{f=0} /^section TWO/{f=1} f && /text_c/'

Como funciona

  • /^section/{f=0}

    Sempre que encontrarmos uma linha começando com section, set f=0.

  • /^section TWO/{f=1}

    Se a linha começar com section TWO, substitua o comando anterior e defina f=1.

  • f && /text_c/

    Se ffor diferente de zero e a linha atual corresponder text_c, imprima a linha.

Responder2

Você também pode fazer isso com sed:

command | sed -n -e '/section TWO/,/section THREE/ { /text_c/p;}'

isso funciona por:

  • -ndiz sedpara não imprimir linhas correspondentes por padrão
  • -esedum script para trabalhar
    • /section TWO/,/section THREE/define nosso intervalo de endereços, então vamos aplicar a próxima função a todas as linhas entre as linhas que correspondem section TWOesection THREE
    • { /text_c/p;}define a função que irá corresponder a uma linha text_ce se encontrar irá pimprimi-la

Responder3

Se o número de linhas que seguem cada seção for constante, você pode usar o '-Ax'opção no grep para imprimirxlinhas após uma correspondência de seção. Isso pode então ser canalizado para um segundo grep que procura seu padrão na 'seção DOIS'.

$ cat file
section ONE
  1 text_a
  1 text_b
  1 text_c  
section TWO
  2_text_a
  2 text_b
  2 text_c  
section THREE
  3 text_a
  3 text_b
  3 text_c 

$ grep -A3 'section TWO' file | grep text_c
  2 text_c

informação relacionada