Exclua todas as linhas que começam com um # de um arquivo
182
Todas as linhas com comentários em um arquivo começam com #. Como posso excluir todas as linhas (e somente aquelas) que começam com #? Outras linhas que contêm #, mas não no início da linha, devem ser ignoradas.
Ele precisa trabalhar com a convenção comum que #blah \<nl>blahconta como uma única "linha lógica" porque a barra invertida escapa à nova linha?
sarnold
@sarnold: além de makequais utilitários usam as 'linhas de emendas de barra invertida antes de terminar um comentário'? As conchas (bash e ksh testadas) não. C e C ++ lidam com emenda de nova linha antes de outro processamento de diretivas de pré-processador, mas são diretivas em vez de comentários.
precisa
@ Jonathan: Incrível. Eu tinha assumido que a \<nl>fuga comum também funcionaria nos comentários. Mas uau, eu estava errado. Ainda não consegui encontrar outro exemplo ... :) Obrigado!
sarnold
Respostas:
302
Isso pode ser feito com uma linha de comando sed :
sed '/^#/d'
Isso diz: "encontre todas as linhas que começam com # e exclua-as, deixando todo o resto".
Estou um pouco surpreso que ninguém tenha sugerido a solução mais óbvia:
grep -v '^#' filename
Isso resolve o problema como indicado.
Mas observe que uma convenção comum é que tudo, de um #até o final de uma linha, seja tratado como um comentário:
sed 's/#.*$//' filename
embora isso trate, por exemplo, um #caractere dentro de uma string literal como o início de um comentário (que pode ou não ser relevante para o seu caso) (e deixa linhas vazias).
Uma linha começando com um espaço em branco arbitrário seguido por #também pode ser tratada como um comentário:
grep -v '^ *#' filename
se espaço em branco for apenas espaços, ou
grep -v '^[ ]#' filename
onde os dois espaços são na verdade um espaço seguido por um caractere de tabulação literal (digite "control-v tab").
Para todos esses comandos, omita o filenameargumento para ler da entrada padrão (por exemplo, como parte de um canal).
Se você também deseja excluir linhas de comentário que começam com algum espaço em branco, use
sed -i '/^\s*#/ d'
Normalmente, você deseja manter a primeira linha do seu script, se for um sha-bang, portanto sed, não exclua as linhas começando com #!. também deve excluir linhas, que contêm apenas um hash, mas nenhum texto. junte tudo:
sed -i '/^\s*\(#[^!].*\|#$\)/d'
Para estar em conformidade com todas as variantes sed, você precisa adicionar uma extensão de backup à -iopção:
Supondo que você egrepsuporte essa sintaxe; versões mais antigas podem não.
Keith Thompson
-3
Aqui está um loop para todos os arquivos com alguma extensão:
ll -ltr *.filename_extension > list.lst
for i in $(cat list.lst | awk '{ print $8 }')# validate if it is the 8 column on ls do
echo $i
sed -i '/^#/d' $i
done
#blah \<nl>blah
conta como uma única "linha lógica" porque a barra invertida escapa à nova linha?make
quais utilitários usam as 'linhas de emendas de barra invertida antes de terminar um comentário'? As conchas (bash e ksh testadas) não. C e C ++ lidam com emenda de nova linha antes de outro processamento de diretivas de pré-processador, mas são diretivas em vez de comentários.\<nl>
fuga comum também funcionaria nos comentários. Mas uau, eu estava errado. Ainda não consegui encontrar outro exemplo ... :) Obrigado!Respostas:
Isso pode ser feito com uma linha de comando sed :
Isso diz: "encontre todas as linhas que começam com # e exclua-as, deixando todo o resto".
fonte
sed /^#/d
sed '/^#/ d' < inputFile.txt > outputFile.txt
sed -i '/^#/d' filepath
.sed -i '' '/^#/d' filepath
no Mac ( porque o sufixo -i é obrigatória )awk '/^#/ && !first { first=1 ; next } { print $0}'
Estou um pouco surpreso que ninguém tenha sugerido a solução mais óbvia:
Isso resolve o problema como indicado.
Mas observe que uma convenção comum é que tudo, de um
#
até o final de uma linha, seja tratado como um comentário:embora isso trate, por exemplo, um
#
caractere dentro de uma string literal como o início de um comentário (que pode ou não ser relevante para o seu caso) (e deixa linhas vazias).Uma linha começando com um espaço em branco arbitrário seguido por
#
também pode ser tratada como um comentário:se espaço em branco for apenas espaços, ou
onde os dois espaços são na verdade um espaço seguido por um caractere de tabulação literal (digite "control-v tab").
Para todos esses comandos, omita o
filename
argumento para ler da entrada padrão (por exemplo, como parte de um canal).fonte
grep -v "^#" filename
O oposto da solução de Raymond:
"não imprima nada, exceto linhas que NÃO começam com #"
fonte
você pode editar diretamente seu arquivo com
Se você também deseja excluir linhas de comentário que começam com algum espaço em branco, use
Normalmente, você deseja manter a primeira linha do seu script, se for um sha-bang, portanto
sed
, não exclua as linhas começando com#!
. também deve excluir linhas, que contêm apenas um hash, mas nenhum texto. junte tudo:Para estar em conformidade com todas as variantes sed, você precisa adicionar uma extensão de backup à
-i
opção:fonte
Você pode usar o seguinte para uma solução awk -
fonte
Esta resposta baseia-se na resposta anterior de Keith .
egrep -v "^[[:blank:]]*#"
deve filtrar as linhas de comentário.egrep -v "^[[:blank:]]*(#|$)"
deve filtrar os comentários e as linhas vazias, como é frequentemente útil.Para obter informações sobre
[:blank:]
e outras classes de caracteres, consulte https://en.wikipedia.org/wiki/Regular_expression#Character_classes .fonte
egrep
suporte essa sintaxe; versões mais antigas podem não.Aqui está um loop para todos os arquivos com alguma extensão:
fonte