Eu tenho um arquivo com comentários:
foo
bar
stuff
#Do not show this...
morestuff
evenmorestuff#Or this
Eu só quero imprimir todo o código não comentado:
foo
bar
stuff
morestuff
evenmorestuff
Ser capaz de remover os comentários de um arquivo é tão importante ... Qual é uma boa maneira de fazer isso?
shell-script
text-processing
awk
sed
grep
Ponto de interrogação
fonte
fonte
awk -F\# '$1!="" { print $1 ;} '
.echo '#' # output a #
seria tratada?Respostas:
Uma maneira de remover todos os comentários é usar
grep
com a-o
opção:Onde
-o
: imprime apenas parte da linha correspondente^
: começo da linha[^#]*
: qualquer caractere, exceto#
repetidas zero ou mais vezesObserve que as linhas vazias também serão removidas, mas as linhas com apenas espaços permanecerão.
fonte
grep -v '^#' file > newfilewithoutcomments
somvar='I am a long complicated string ## with special characters' # and I am a comment
não será tratada corretamente.grep -o '^[^#].*' file
sed
solução tem apenas uma linha em branco, parece um argumento sólido para usar outra resposta, a menos que esteja faltando alguma coisa?grep
talvez? Tente mudargrep
paracommand grep
, se você ainda vir espaços postar a entrada de amostra.Eu acredito que
sed
pode fazer um trabalho muito melhor disso do quegrep
. Algo assim:Explicação
sed
por padrão, examinará seu arquivo linha por linha e imprimirá cada linha após possivelmente aplicar as transformações entre aspas. (sed '' your_file
apenas imprimirá todas as linhas inalteradas).sed
dois comandos para executar em cada linha (eles são separados por ponto e vírgula)./^[[:blank:]]*#/d
. Em inglês, isso significa que se a linha corresponder a um hash no início (precedida por qualquer número de espaços em branco à esquerda), exclua essa linha (ela não será impressa).s/#.*//
. Em inglês, substitua uma marca de hash seguida de tantas coisas quanto você puder encontrar (até o final da linha) por nada (nada é o espaço vazio entre as duas últimas//
).fonte
mystring="Hello I am a #hash"
se tornarámystring="Hello I am a"
crontab
apenas permitem comentários de linha completa, com ou sem espaço em branco à esquerda, mas não permitem comentários finais em uma linha. A lógica é MUITO mais simples. Use apenas a primeira das duas instruções Sed nesta resposta para um stripper de comentário do crontab.)#
(na coluna 1), existe algum benefício ased
maisgrep -v "^#"
?Você pode obter a saída necessária usando o comando sed. O comando abaixo havia feito o truque para mim.
Onde
#.*$
- Regexp filtrará toda a sequência que começa com#
até o final da linhaAqui, precisamos remover essas linhas e substituí-las por vazias, para pular a peça de "substituição".
g
- mencionando a pesquisa repetida do padrão até o final do arquivo.Sintaxe geral de sed:
s/regexp/replacement/flags FileName
fonte
sed
comando ...print "#tag" # Print a hashtag.
Como outros já apontaram, o sed e outras ferramentas baseadas em texto não funcionarão bem se alguma parte do script se parecer com comentários, mas na verdade não for. Por exemplo, você pode encontrar um # dentro de uma string, ou o bastante comum
$#
e${#param}
.Eu escrevi um formatador de shell chamado shfmt , que possui um recurso para reduzir o código. Isso inclui remover comentários, entre outras coisas:
O analisador e a impressora são pacotes Go, portanto, se você deseja uma solução personalizada, deve ser bastante fácil escrever um programa Go de 20 linhas para remover os comentários da maneira exata desejada.
fonte
Você pode usar a correspondência invertida assim:
-v, --invert-match Inverte a sensação de correspondência, para selecionar linhas não correspondentes. (-v é especificado pelo POSIX.)
fonte
evenmorestuff
no exemplo do OP.grep -o '^[^#]*' file
seria a melhor solução. isso já é explicado por jimmij. obrigado pela sua revisãoprint "#tag" # Print a hashtag.
Eu gosto da resposta de Joseph, mas precisava dela para remover // os comentários também, então eu a modifiquei um pouco e testei no redhat
Aposto que há uma maneira melhor de remover linhas em branco do que usar strings, mas foi a solução rápida e suja que usei.
-Felicidades
fonte
print "#tag" # Print a hashtag.
Isso funcionou para mim
fonte
print "#tag" # Print a hashtag.
Ele usa
#
como separador de colunas e mantém apenas a primeira coluna (isso é tudo antes#
).fonte
YOUR_FILE
for um script que contenha esses comandos, o script será deixadocat YOUR_FILE | cut -'
no arquivo nessa linha.Use expressão como
: -v: fará correspondência invertida
: #: corresponderá a todas as linhas começando com #
: $ ^: corresponderá a todas as linhas em branco
fonte
#
item corresponderá a qualquer lugar da linha e removerá a linha inteira.A melhor solução seria usar o comando:
sed -i.$(date +%F) '/^#/d;/^$/d' ntp.conf
O -i é a edição no local, mas o prefixo diretamente a seguir informa ao sed para criar um backup. Nesse caso, com uma extensão de data (ntp.conf.date). Executamos dois comandos, cada um com um espaço de endereço, o primeiro exclui as linhas comentadas e o segundo, separado do primeiro por ponto e vírgula, exclui as linhas em branco.
Encontrei esta solução em: theurbanpenguin.com
fonte
Nenhuma das outras respostas parece fazer essa justiça, elas deixam em linhas vazias ou em linhas onde o comentário não está no primeiro caractere. Acabei usando isso:
Isso configura um alias, para que você não precise memorizá-lo (o que é impossível para começar). Abra uma nova sessão e você terá o novo
nocom
comando. Então você pode apenasFelicidades.
fonte
.*$
no primeiro regex - a âncora não é útil e você não está capturando o texto correspondente para usar em uma substituição. use just^\s*
print "#tag" # Print a hashtag.
Após a 2ª resposta de Joseph R., adiciono
/^$/d
para remover a linha em branco.fonte
Estou postando o que funciona para mim e parece fazer mais sentido, depois de ler os outros, com explicações. Algumas postagens chegaram perto, mas ainda não pude comentar (porque sou novato):
-E
= interpreta o seguinte padrão como uma expressão regular, semelhante ao uso do egrep-v
= imprime a inversão do padrão (as linhas que não correspondem à expressão serão impressas)"(^#.*|^$)"
= isso possui um canal que designa uma instrução OR. Essa expressão diz para imprimir qualquer linha que comece com a#
(e qualquer outra coisa depois dela) OU qualquer linha com zero caracteres entre o início e o final da linha.O
-v
imprimirá na tela a inversão disso, que será qualquer linha com caracteres que não comece com a#
.fonte
print "#tag" # Print a hashtag.