linhas awk ou sed entre o mesmo padrão, incluindo a primeira correspondência

0

Este é o texto:

* Tue This is the first line

– info 1

– info 2

– info 3

* Wed This is not to be included

A saída deste texto deve ser esta:

* Tue This is the first line

– info 1

– info 2

– info 3

NOTA: Eu tentei o awk e o sed, mas não consegui gerar minha saída. O problema é que o START e o END são os mesmos "*" (asterisco) e o primeiro deve ser incluído na saída.

    
por foot3print 14.03.2017 / 12:25

3 respostas

0

Espero entender isso corretamente. Esse script removerá tudo da linha que começa com o segundo * até o final do buffer, produzindo a saída desejada do exemplo:

sed -n 'H;1h;$x;$s/\(\*[^*]*\)\n\*.*$//p'

Explicação anexar todas as linhas ( H ) ao buffer de espera. Para o último buffer de troca de linha e padrão ( $x ), você tem o arquivo inteiro como um padrão. Nesse padrão, a parte a ser mantida é definida em \(\) e mantida ( ), enquanto tudo a partir da nova linha com * é excluído.

Isso se ajusta à sua descrição, mas se não se encaixar em todos os exemplos possíveis, você pode modificar o script.

    
por 14.03.2017 / 12:53
0
perl -lne 'if ( m?^\*? ... m?^\*? ) { print if !// || !$a++ }'

sed -e '
   /^\*/!d
   :loop
       $q; N
   /\n\*/!bloop
   s/\(.*\)\n.*//;q
'

sed -e '
   /^\*/!d
   :loop
      n
   //!bloop
   Q
'
    
por 14.03.2017 / 13:15
0

Salvar texto de amostra na variável:

$ SAMPLE=$(cat <<EOF
* Tue This is the first line

– info 1

– info 2

– info 3

* Wed This is not to be included
* Tue This is the first line

– info 1

– info 2

– info 3

* Wed This is not to be included
EOF
)

Use awk para processar seu $SAMPLE :

$ awk '{if($1~"\*"){if(p==1){p=0;next}else{p=1}}if(p==1){print $0}}' <<<"$SAMPLE"
* Tue This is the first line

– info 1

– info 2

– info 3

* Tue This is the first line

– info 1

– info 2

– info 3

EDITAR

Como sugerido nos comentários, é surpreendentemente elegante awk solution:

$ awk '/^\*/{p=!p};p' <<<"$SAMPLE"
* Tue This is the first line

– info 1

– info 2

– info 3

* Tue This is the first line

– info 1

– info 2

– info 3

Como funciona:

  • /^\*/{p=!p}; - alterna o valor de p para 1 e 0 . Ele se tornará 1 quando regex /^\*/ for encontrado pela primeira vez. Na segunda vez em que for encontrado, p se tornará 0 e assim por diante.

  • p - isso é equivalente a p{print} . Como print é a ação padrão em awk , ela sempre será impressa quando a pré-condição for avaliada como true , nesse caso, quando p se tornar 1 .

por 14.03.2017 / 12:53