Eu tentei sed e awk, mas não está funcionando, pois o personagem envolve "/", que já está no comando como delimitador.
Por favor, deixe-me saber como posso conseguir isso.
Abaixo está um exemplo de exemplo. Queremos remover as seções comentadas, ou seja, /*.....*/
/*This is to print the output
data*/
proc print data=sashelp.cars;
run;
/*Creating dataset*/
data abc;
set xyz;
run;
text-processing
Sharique Alam
fonte
fonte
INSERT INTO string_table VALUES('/*'), ('*/'), ('/**/');
)Respostas:
Eu acho que encontrei uma solução fácil!
ALGUMAS ATUALIZAÇÕES:
Citação do usuário ilkachu (texto original dos comentários do usuário):
Eu brinquei um pouco com as opções do gcc: -fpreprocessed desativará a maioria das diretivas e expansões de macro (exceto #define e #undef aparentemente). Adicionar -dD também deixará define em; e std = c89 pode ser usado para ignorar o novo estilo // comentários. Mesmo com eles, o cpp substitui os comentários por espaços (em vez de removê-los) e recolhe espaços e linhas vazias.
Mas acho que ainda é razoável e uma solução fácil para a maioria dos casos, se você desativar a expansão de macro e outras coisas, acho que obterá bons resultados ... - e sim, você pode combinar isso com o shell script para melhorar ... e muito mais...
fonte
cpp
vai fazer muito mais do que a remoção de comentários (processo#include
, expandir macros, incluindo builtin queridos ...)tail -n +7
apenas removerá as 7 primeiras linhas, não impedirá o#include
processamento ou as expansões de macro. Tenteecho __LINE__ | cpp
por exemplo. Ouecho '#include /dev/zero' | cpp
-P
modo se fizer isso. (Isto pode eliminar a necessidade de utilizaçãotail
.)-fpreprocessed
desativará a maioria das diretivas e expansões de macro (exceto#define
e#undef
aparentemente). Adicionar-dD
também deixa define dentro; estd=c89
pode ser usado para ignorar novos//
comentários de estilo . Mesmo com eles,cpp
substitui os comentários por espaços (em vez de removê-los) e recolhe espaços e linhas vazias.Certa vez, inventei isso que podemos refinar:
para lidar com mais alguns casos de canto.
Observe que se você remover um comentário, poderá alterar o significado do código (
1-/* comment */-1
é analisado como1 - -1
while1--1
(que você obteria se removesse o comentário) causaria um erro). É melhor substituir o comentário por um caractere de espaço (como fazemos aqui) em vez de removê-lo completamente.O exemplo acima deve funcionar corretamente nesse código ANSI C válido, por exemplo, que tenta incluir alguns casos de canto:
O que fornece esta saída:
Ambos imprimem a mesma saída quando compilados e executados.
Você pode comparar com a saída de
gcc -ansi -E
para ver o que o pré-processador faria nele. Esse código também é um código C99 ou C11 válido, no entanto,gcc
desabilita o suporte a trigrafs por padrão, para que não funcione, agcc
menos que você especifique o padrão comogcc -std=c99
ougcc -std=c11
ou adicione a-trigraphs
opção).Também funciona neste código C99 / C11 (não-ANSI / C90):
(compare com
gcc -E
/gcc -std=c99 -E
/gcc -std=c11 -E
)O ANSI C não suporta o
// form
comentário.//
não é válido de outra maneira no ANSI C, portanto, não apareceria lá. Um caso artificial em que//
pode realmente aparecer no ANSI C (como observado aqui , e você pode achar o restante da discussão interessante) é quando o operador stringify está em uso.Este é um código ANSI C válido:
E na época da discussão em 2004, de
gcc -ansi -E
fato a expandiu para"//not a comment"
. No entanto, hoje,gcc-5.4
retorna um erro, então duvido que encontraremos muito código C usando esse tipo de construção.O
sed
equivalente GNU pode ser algo como:Se seu GNU
sed
é muito antigo para suportar-E
ou-z
, você pode substituir a primeira linha por:fonte
gcc -std=c11 -E -P
(-ansi
é apenas outro nome para-std=c90
).??'
), portanto, comparamos comcpp -ansi
essas e C99 / C11 ... uma (como// xxx
), daí que compara comcpp
(oucpp -std=c11
...)com
sed
:ATUALIZAR
suporta todo o possível (comentário em várias linhas, dados após [ou e] antes);
corre:fonte
proc print data 2nd /*another comment is here*/
Remova linhas em branco, se houver:
Edit - a versão mais curta de Stephane:
fonte
-0777
como uma maneira mais curta de fazerBEGIN{$/=undef}
.*?
vez de.+?
se também/**/
seja um comentário válido.Solução usando o comando SED e nenhum script
Olha Você aqui:
sed 's/\*\//\n&/g' test | sed '/\/\*/,/\*\//d'
Nota: isso não funciona no OS X, a menos que você instale
gnu-sed
. Mas funciona em distribuições Linux.fonte
-i
opção para editar o arquivo no local em vez de redirecionar a saída para o novo arquivo. ou muito mais seguro-i.bak
para arquivo de backupsed
opera em uma linha por vez, mas alguns dos comentários na entrada abrangem várias linhas. Conforme /unix//a/152389/90751 , você pode primeiro usartr
para transformar as quebras de linha em algum outro caractere. Em seguida, vocêsed
pode processar a entrada como uma única linha e usartr
novamente para restaurar as quebras de linha.Usei bytes nulos, mas você pode escolher qualquer caractere que não apareça no seu arquivo de entrada.
*
tem um significado especial em expressões regulares, portanto, precisará ser escapado\*
para corresponder a um literal*
..*
é ganancioso - ele corresponderá ao texto mais longo possível, incluindo mais*/
e/*
. Isso significa o primeiro comentário, o último comentário e tudo mais. Para restringir isso, substitua.*
por um padrão mais rígido: os comentários podem conter qualquer coisa que não seja um "*" e também "*" seguido por qualquer coisa que não seja um "/". Execuções de múltiplos*
s também devem ser consideradas:Isso removerá quaisquer quebras de linha nos comentários de várias linhas, ou seja.
se tornará
Se não era isso que se queria,
sed
pode ser dito para manter uma das quebras de linha. Isso significa escolher um caractere de substituição de quebra de linha que possa ser correspondido.O caractere especial
\f
e o uso de uma referência anterior que pode não corresponder a nada não garantem que funcione conforme o esperado em todas assed
implementações. (Confirmei que funciona no GNU sed 4.07 e 4.2.2.)fonte
test.sas
no meio do pipeline lá, entãosed
lê diretamente, e o primeirotr
não tem efeito. Você precisa usarcat test.sas | tr ...
usando uma linha sed para remover comentários:
fonte