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.
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 #!
.
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. 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.
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
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*#(?!!)/'
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.
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.
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}'
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
Tags sed