Posso apagar apenas a primeira linha correspondente usando sed?

0

Eu tenho um arquivo testfile.txt contendo

pippo=x
pluto=y
1234=z

Gostaria de excluir apenas a primeira linha correspondente a /^[a-z]\+=/ (a primeira linha deste exemplo).

Eu tentei com o seguinte comando, mas sem sucesso:

sed   '/^[a-z]\+=/,+0d' testfile.txt

mas as primeiras duas linhas são excluídas.

Existe uma maneira de fazer essa tarefa usando sed ?

Atenciosamente

    
por user609012 22.06.2016 / 11:52

2 respostas

1

@ John1024 Desculpe, mas sua solução funciona somente se a primeira linha correspondente for a primeira linha do arquivo.

Eu resolvi o problema com o seguinte código sed -r '0,/^[a-z]\+=/{//d;}' testfile.txt , mas ainda estou convencido de que minha solução anterior deveria ter funcionado mesmo com o posix sed.

Infacta a idéia era dar como segundo endereço de linha um deslocamento de 0 linhas ... mas ainda apaga também a seguinte linha, isso soa como um bug.

de man sed no ubuntu 14.04

... addr1,+N Will match addr1 and the N lines following addr1. ...

    
por 22.06.2016 / 13:16
1

O problema com o seu comando sed

$ sed '/^[a-z]\+=/,+0d' testfile.txt

é que o script sed é aplicado a todas as linhas dos dados de entrada.

O +0 (que é uma extensão do GNU) significa que seu script é equivalente a

$ sed '/^[a-z]\+=/d' testfile.txt

e a primeira e segunda linhas seriam excluídas, como você percebeu.

Por acaso, você obterá exatamente o mesmo efeito usando +1 , mas por outros motivos. O comando d , em vez de ser aplicado à linha um e dois individualmente, seria aplicado às duas primeiras linhas devido à correspondência na primeira linha (ou seja, o intervalo do comando d seria as linhas um e mais um +1 ). Isso não exclui a linha três porque está fora do intervalo.

A solução sed do GNU

$ sed '0,/^[a-z]\+=/{//d}' testfile.txt

que o usuário @Whitefield postou funciona e é bastante bom (embora a opção -r seja desnecessária e o% start 0 possa ser alterado para 1 neste caso, se você quiser ser mais POSIX-ish) .

Uma variante BSD sed da mesma abordagem seria parecida com

$ sed '1,/^[a-z]+=/{/^[a-z]+=/d
  }' testfile.txt

Escapar de + é necessário apenas se o seu sed implementar "expressões regulares básicas obsoletas" em vez de "expressões regulares básicas modernas". Tanto o BSD sed quanto o GNU sed no meu sistema (Mac OS X) parecem ser do tipo "moderno". O POSIX não tem essa distinção e ler os manuais ( re_format(7) no BSD, que faz essa distinção) e a especificação POSIX lado a lado faz minha cabeça girar.

    
por 23.06.2016 / 19:02

Tags