Como remover uma linha entre duas linhas

3

Eu tenho milllions de registros em um arquivo que se parece com isso

echo "NEW Cell"
grep "2553,24" out.2A25.20090308.64436.7.HDF.txt.text = 22.58   5.39  82.09 237
echo "NEW Cell"
grep "2555,20" out.2A25.20090308.64436.7.HDF.txt.text = 24.72   5.58  82.05 237
echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
echo "NEW Cell"
grep "2560,24" out.2A25.20090308.64436.7.HDF.txt.text = 19.38   5.54  82.30 170
echo "NEW Cell"

Agora, quero excluir a linha com "grep", desde que seja a ÚNICA linha entre as linhas que contêm "Nova célula". Isto é, se houver uma linha de grep entre a nova célula, essa linha deve ser excluída.

Como fazer isso?

Minha saída deve parecer

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
    
por geet 23.11.2017 / 09:58

4 respostas

3

AWK solução:

awk 'NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }
     /NEW Cell/{ f=1; n=NR+2; r=$0; next }
     f && n-NR==1 && /^grep /{ gr=$0; next }1' file
  • /NEW Cell/{ f=1; n=NR+2; r=$0; next } - ao encontrar linha com NEW Cell

    • f=1 = definir sinalizador ativo f=1
    • n=NR+2 - define n como número máximo das seguintes linhas a serem processadas (2 próximas linhas)
    • r=$0 - capturando a linha
    • next - pula para o próximo registro
  • f && n-NR==1 && /^grep / - ao encontrar a segunda linha (garantida por n-NR==1 ) que começa com grep keyword

    • gr=$0; next - capturando grep linha e pula para o próximo (terceiro) registro
  • NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr } - ao encontrar a terceira linha crucial (assegurada por NR==n )

    • if (/NEW Cell/) { f=0 } - se a terceira linha na seção processada contiver NEW Cell - redefinir o processamento atual com f=0 (todas as linhas capturadas anteriormente são ignoradas)
    • else print r ORS gr - caso contrário, imprima todas as linhas capturadas anteriormente

A saída:

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
    
por 23.11.2017 / 10:31
2

Solução compacta com sed :

sed '/NEW Cell/!{H;d;};x;/\n.*\n/!d'

Se a linha não contiver NEW Cell execute H para anexar a linha ao espaço de espera e d para interromper o processamento dessa linha.

Portanto, outros comandos são aplicados apenas a NEW Cell lines: O x troca espaço de padrão e mantém espaço, portanto a linha agora está no espaço de espera e outras linhas podem ser anexadas, enquanto o espaço de padrão contém tudo anexado a última linha NEW Cell . Sua exigência é que haja mais de uma linha entre as linhas NEW Cell , portanto, deve haver pelo menos duas novas linhas no espaço de padrão. Se não, exclua sem saída: /\n.*\n/!d .

    
por 23.11.2017 / 14:20
1

Com rudimentary awk ...

A versão 1 excluirá apenas grep linhas que seguem a descrição do OP:

awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
     else { f=1; s=$0 } } ! /^echo/ { print; f=0 } \
     ! /^echo/ && ! /^grep/ { print }' inputfile

A versão 2 excluirá o solo grep linhas, assim como a linha precedente não-grep, que segue a saída de amostra do OP:

awk '/^grep/ { if (f) { if (length(s) > 0) { print s; s="" } print } \
    else { f=1; s=s "\n" $0 } } /^echo/ { s=$0; f=0 } \
    ! /^echo/ && ! /^grep/ { print }' inputfile

Forma legível da versão 2 ...

/^grep/ { 
   if (found) {  # found==true : already encountered first grep line
       if (length(save) > 0) {
          print save
          save=""
       }
       print
   } else {
       found=1
       save=save "\n" $0  # append the first grep line to saved preceding line
   }
}

/^echo/ { 
    save=$0  # save this line for possible later printing
    found=0
}

# print anything else
! /^echo/ && ! /^grep/ { print }

Esse formulário longo pode ser exibido colocando o conteúdo em um arquivo (por exemplo, awkfile ) e awk -f awkfile inputfile .

    
por 23.11.2017 / 10:36
1
gawk '
/\n.+\n/{
    printf("%s%s", RS, $0);
}' RS='echo "NEW Cell"\n' input.txt

Explicação:

  1. RS='echo "NEW Cell"\n' - RS é o separador de registro de entrada, por padrão, uma nova linha. Agora ele é alterado para echo "NEW Cell"\n , portanto, todas as ocorrências dessa sequência serão removidas e todos os caracteres entre elas se tornarão o item de registro.
  2. /\n.+\n/{ - somente para registros que correspondem a esse padrão - nova linha, um ou mais caracteres, nova linha. Portanto, ele corresponde apenas aos registros de várias linhas, o registro de linha única não corresponde, porque tem apenas um \n .
  3. printf("%s%s", RS, $0); - imprime o registro, precedido pelo RS ( echo "NEW Cell"\n ).

Resultado

echo "NEW Cell"
grep "2557,20" out.2A25.20090308.64436.7.HDF.txt.text = 19.75   5.62  82.11 170
grep "2557,21" out.2A25.20090308.64436.7.HDF.txt.text = 24.34   5.58  82.13 120
grep "2558,22" out.2A25.20090308.64436.7.HDF.txt.text = 22.2   5.57  82.19 120
echo "NEW Cell"
grep "2560,22" out.2A25.20090308.64436.7.HDF.txt.text = 24.69   5.62  82.25 160
grep "2561,23" out.2A25.20090308.64436.7.HDF.txt.text = 24.74   5.60  82.30 120
    
por 23.11.2017 / 19:50

Tags