Remover linhas que não iniciam com um padrão de um determinado conjunto de padrões

8

Eu tenho um arquivo que contém dados como este:

report aaaaaaaa  
-  ..  
-th bbbbbbbbb  
-to ccccccccc

.. --.

Pergunta: desejo remover qualquer linha que não comece com as seguintes sequências:

report  
-th  
-to

isso significa que a saída do desejo removerá todos os pontos e hashes indesejados do meio e ficará assim:

report aaaaaaaa  
-th bbbbbbbbb  
-to ccccccccc

sed / awk / grep / etc qualquer solução que funcione.

    
por Rana Khan 06.11.2013 / 22:37

6 respostas

12

Usando sed para modificar o arquivo:

sed -i '/^\(report\|-t\(h\|o\)\)/!d' your_file

Isso instrui sed a excluir todas as linhas que não correspondam ao padrão. O próprio padrão é ^ (início da linha), seguido por report ou -t seguido por h ou o .

Você deve observar que isso não é uma modificação real no local: sed cria uma cópia de backup temporária e sobrescreve o arquivo original com ela.

Se você quiser que sed mantenha uma cópia de backup do arquivo original (o que pode ser uma boa ideia se o arquivo contiver dados críticos), forneça a extensão -i para criar um arquivo de backup:

sed -i'.bak' -e '/^\(report\|-t\(h\|o\)\)/!d' your_file

modificará your_file e criará um backup do original chamado your_file.bak .

Uma nota lateral

Por favor, não interprete mal minhas intenções ou se ofenda com isso, mas notei que você tem muitas questões relacionadas a processamento de texto / regex similares. Eu aconselho você a começar a aprender sed , awk e grep por conta própria para ajudar a acelerar sua produtividade. Mais uma vez, não me interpretem mal, estou muito feliz em ajudar (como a maioria das pessoas por aqui); é só que eu acho que você se beneficiará enormemente de pegar essas ferramentas para o seu uso diário.

Apenas para provar o quão útil as pessoas estão por aqui, considere a sugestão do @ slm nos comentários abaixo e sinta-se à vontade para baixar esta sala de chat a qualquer momento para perguntas.

    
por 06.11.2013 / 22:52
10

Você pode usar o grep simples para isso:

$ grep -e '^report\|^-th\|^-to' filename
    
por 06.11.2013 / 22:49
2

Usando sed :

sed -n -e '/^report\|^-th\|^-to/p' filename
    
por 06.11.2013 / 22:51
2

Usando awk :

awk '/^report|^-t[ho]/' file
    
por 06.11.2013 / 22:50
1

O questionador fez dois comentários:

  • que deseja remover qualquer linha que não comece com "report" ou "-th" ou "-to".
  • a saída desejada deve remover "todos os pontos e hashes médios não desejados (sic)"

As soluções, neste momento, abordam o primeiro ponto e, portanto, também o segundo. Mas suponha que o arquivo seja maior e se pareça com:

report aaaaaaaa  
-  ..  
-th bbbbbbbbb  
-to ccccccccc
anything else
.. --.
-tp ddd
-tq eee
     -  -----

O problema não seria abordado no segundo ponto do OP?

sed -r -i.bak '/^[ |.|-]*$/d' input-file 

faz o trabalho de remover linhas presumivelmente indesejadas contendo apenas espaços, pontos e traços e reter o resto, seja lá o que for.
Eu acho que o risco de qualquer abordagem é que a natureza do arquivo não está definida corretamente.

    
por 07.11.2013 / 04:22
0

Usando o Perl:

perl -ne 'print if /^report|^-t[ho]/' filename > newfile

ou, para editar no local (como sed , perl também fará um backup temporário, então isso não é edição ):

perl -i.bak -ne 'print if /^report|^-t[ho]/' filename

Isso fará uma cópia do arquivo original chamado filename.bak e substituirá o arquivo original pela versão editada.

    
por 07.11.2013 / 00:59