AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 406507
Accepted
geet
geet
Asked: 2017-11-24 00:58:02 +0800 CST2017-11-24 00:58:02 +0800 CST 2017-11-24 00:58:02 +0800 CST

Como remover uma única linha entre duas linhas

  • 772

Eu tenho milhões de registros em um arquivo que se parece com este

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, desejo excluir a linha com "grep" com a condição de que seja a ÚNICA linha entre as linhas que contêm "Nova célula". Ou seja, se houver uma linha de grep entre a nova célula, essa linha deverá ser excluída.

Como fazer isso?

Minha saída deve se parecer com,

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
awk sed
  • 4 4 respostas
  • 630 Views

4 respostas

  • Voted
  1. Best Answer
    RomanPerekhrest
    2017-11-24T01:31:11+08:002017-11-24T01:31:11+08:00

    AWKsoluçã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 comNEW Cell

      • f=1= definir sinalizador ativof=1
      • n=NR+2- definir ncomo número máximo das seguintes linhas a serem processadas (2 próximas linhas)
      • r=$0- captura da linha
      • next- pular para o próximo registro
    • f && n-NR==1 && /^grep /- ao encontrar a 2ª linha (garantida por n-NR==1) que começa com a palavra- grepchave

      • gr=$0; next- capturar greplinha e pular para o próximo (terceiro) registro
    • NR==n{ if (/NEW Cell/) { f=0 } else print r ORS gr }- ao encontrar a 3ª linha crucial (garantida por NR==n)

      • if (/NEW Cell/) { f=0 }- se a 3ª linha na seção processada contiver NEW Cell- redefina 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
    
    • 3
  2. Philippos
    2017-11-24T05:20:57+08:002017-11-24T05:20:57+08:00

    Solução compacta com sed:

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

    Se a linha não contiver NEW Cellexecute Hpara anexar a linha ao espaço de retenção e dinterromper o processamento dessa linha.

    Portanto, outros comandos são aplicados apenas às NEW Celllinhas: O xespaço de padrão de trocas e o espaço de retenção, portanto, a linha agora está no espaço de retenção e outras linhas podem ser anexadas, enquanto o espaço de padrão contém tudo o que foi anexado à última NEW Celllinha. Seu requisito é que haja mais de uma linha entre as NEW Celllinhas, portanto, deve haver pelo menos duas novas linhas no espaço do padrão. Caso contrário, exclua-o sem saída: /\n.*\n/!d.

    • 2
  3. B Layer
    2017-11-24T01:36:54+08:002017-11-24T01:36:54+08:00

    Com rudimentar awk...

    A versão 1 excluirá apenas grepas 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á grepas linhas solo, bem como a linha não grep anterior 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 }
    

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

    • 1
  4. MiniMax
    2017-11-24T10:50:08+08:002017-11-24T10:50:08+08:00
    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 é alterado para o echo "NEW Cell"\n, assim, todas as ocorrências desta string 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 este padrão - nova linha, um ou mais caracteres, nova linha. Portanto, ele corresponde apenas a registros multilinha, o registro de linha única não corresponde, porque possui apenas um arquivo \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
    
    • 1

relate perguntas

  • Reorganize as letras e compare duas palavras

  • Embaralhamento de arquivo de várias linhas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Matriz JSON para bash variáveis ​​usando jq

    • 4 respostas
  • Marko Smith

    A data pode formatar a hora atual para o fuso horário GMT? [duplicado]

    • 2 respostas
  • Marko Smith

    bash + lê variáveis ​​e valores do arquivo pelo script bash

    • 4 respostas
  • Marko Smith

    Como posso copiar um diretório e renomeá-lo no mesmo comando?

    • 4 respostas
  • Marko Smith

    conexão ssh. Conexão X11 rejeitada devido a autenticação incorreta

    • 3 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Marko Smith

    comando systemctl não funciona no RHEL 6

    • 3 respostas
  • Marko Smith

    rsync porta 22 e 873 uso

    • 2 respostas
  • Marko Smith

    snap /dev/loop em 100% de utilização -- sem espaço livre

    • 1 respostas
  • Marko Smith

    chave de impressão jq e valor para todos no subobjeto

    • 2 respostas
  • Martin Hope
    EHerman Matriz JSON para bash variáveis ​​usando jq 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux A data pode formatar a hora atual para o fuso horário GMT? [duplicado] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC Como posso copiar um diretório e renomeá-lo no mesmo comando? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve Como as permissões de arquivo funcionam para o usuário "root"? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey Como baixar o pacote não instalá-lo com o comando apt-get? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao Por que os diretórios /home, /usr, /var, etc. têm o mesmo número de inode (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg — o comando list-keys gera uid [ desconhecido ] depois de importar a chave privada para uma instalação limpa 2017-11-26 18:26:02 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve