tir delete a linha começa com # mas não com #! (scripts de shell)

4

Para excluir a linha com # , a seguinte linha pode funcionar:

sed -i "/^\(\s\)*\#/d"

mas o que eu quero é excluir as linhas que começam com # e não com #! .

    
por user238292 29.06.2017 / 11:25

7 respostas

14

sed -i -e '/^\s*#\([^!]\|$\)/d'

Onde:

  • ^ início da linha
  • \s* zero ou mais caracteres em branco
  • # uma marca de hash
  • \([^!]\|$\) seguido por um caractere que não é ! ou fim de linha.
por 29.06.2017 / 11:31
10
sed -i -e '/^#!/p' -e '/^#/d' file

Isto irá percorrer o arquivo linha por linha e quando encontrar uma linha começando com #! , será impressa pela primeira expressão. Em seguida, ele será excluído do espaço de padrão pela segunda expressão (ou seja, não será impresso um tempo de segundo pelo comando padrão p , que está em vigor quando não estiver usando sed -n ). / p>

Uma linha que começa com apenas # será ignorada pela primeira expressão, mas será excluída pela segunda expressão.

Qualquer outra linha será impressa pelo comando p padrão.

Para permitir espaços em branco na frente do # (e excluir essas linhas também):

sed -i -e '/^[[:blank:]]*#!/p' -e '/^[[:blank:]]*#/d' file

A expressão [[:blank:]] corresponderá a um caractere de espaço ou tabulação.

Como Stéphane mencionou os comentários, a alteração de p para b na primeira expressão permitiria que o script sed continuasse com a próxima linha de entrada sem considerar a segunda expressão, se a primeira expressão corresponder. O comando b ramifica para um rótulo predefinido ou para o final do script sed se nenhum rótulo for fornecido. Isso seria uma otimização.

    
por 29.06.2017 / 11:43
6

Para "e" dois endereços, você precisa de um grupo de comando ( {...;} ):

sed '/^[[:space:]]*#/{/^#!/!d;}' < file

Com o GNU sed , você pode usar -i para inplace, substituir [[:space:]] por \s (assumindo uma versão recente) e omitir o ; :

sed -i '/^\s*#/{/^#!/!d}' file

Você pode aninhar vários, mas cuidado com isso, você não pode ter nada depois do } . Então, para A e B e não C e não D , isso seria:

sed '/A/{/B/{/C/!{/D/!d;}' -e '}' -e '}' < file

Ou:

sed '
  /A/{
    /B/{
      /C/!{
        /D/!d
      }
    }
  }' < file
    
por 29.06.2017 / 12:00
4

Use a antecipação negativa em Perl:

perl -ne 'print unless /#(?!!)/'

Isso remove as linhas que contêm # não seguidas por ! . Se você quer combinar o # somente no começo de uma linha, provavelmente precedido por espaço em branco, use

perl -ne 'print unless /^\s*#(?!!)/'
    
por 29.06.2017 / 11:31
2

Resumo: remova todos os comentários não-shebang.

sed -e '1{/^\s*\#/{/^\#!/!d}}' -e '1!{/^\s*\#/d}' file

Seu comando foi modificado para usar aspas simples (sem duplo \ ):

sed '/^\(\s\)*\#/d'

irá funcionar quase que apenas adicionando os detalhes que (após o #) deve haver algo que não seja um asterisco [^!] sed '/^\(\s\)*\#[^!]/d'. But that will fail with a line that is empty after the comment ( # ').

Para isso, precisamos afirmar que a linha terminou ( $ ).

Para isso, precisaremos do uso da sintaxe estendida ([^!]|$) :

sed -E '/^\s*\#([^!]|$)/d'

Ou mais portátil:

sed -E '/^[ \t]*\#([^!]|$)/d'

No entanto, para um script, apenas a primeira linha que começa como #! é importante.
Todas as outras linhas que começam com espaço opcional e # são comentários:

sed -e '1{/^#!/!d}' -e '1!{/^[ \t]*#/d}' file

O que significa:

Primeiro -e

if the first line start with a comment (space and #) but does not start exactly with #! it is erased.

Segundo -e

other lines (1!) that start with an optional space and # are removed.

    
por 29.06.2017 / 19:21
0

Isso funcionou para mim:

$ cat test.sed 
  # delete this one

  #! don't delete this one

        # delete this too

Comando:

$ sed -i -e '/^[[:space:]]*#[^!].*/d' test.sed

Resultado:

$ cat test.sed 

  #! don't delete this one

Bem, esse comando não excluirá linhas com apenas # solitário. Então, mantenho esta resposta para mostrar por que você precisa se referir a outras soluções.

    
por 29.06.2017 / 14:14
0

Presumivelmente, você deseja excluir todas as linhas de comentários (começando com qualquer espaço em branco seguido por # ), exceto o she-bang, que precisa estar na primeira linha a ser detectada. / p>

Você pode usar o mesmo comando de substituição se você o restringir para considerar apenas tudo a partir da linha 2; em sed notação que é o intervalo 2,$ . Você restringe os comandos sed a um intervalo prefixando-os com esse intervalo:

sed "2,${/^\(\s\)*\#/d}"

ou com a cotação do shell que permite espaços de leitura mais legíveis e sem agrupamento de expressão regular desnecessário:

sed -e '2,${/^\s*#/d}'

Exemplo

Entrada:

#!/path/to/a/shebang-command
# This is the first comment

command 1
  # another comment
  command 2
# Final comment

Saída:

#!/path/to/a/shebang-command

command 1
  command 2
    
por 29.06.2017 / 21:14

Tags