Intenté sed y awk, pero no funciona ya que el carácter implica "/", que ya está al mando como delimitador.
Por favor, hágame saber cómo puedo lograr esto.
A continuación hay un ejemplo de ejemplo. Queremos eliminar las secciones comentadas, es decir /*.....*/
/*This is to print the output
data*/
proc print data=sashelp.cars;
run;
/*Creating dataset*/
data abc;
set xyz;
run;
text-processing
Sharique Alam
fuente
fuente
INSERT INTO string_table VALUES('/*'), ('*/'), ('/**/');
)Respuestas:
¡Creo que encontré una solución fácil!
ALGUNAS ACTUALIZACIONES:
Cita del usuario ilkachu (texto original de los comentarios del usuario):
Jugué un poco con las opciones para gcc: -fpreprocessed deshabilitará la mayoría de las directivas y expansiones de macros (excepto #define y #undef aparentemente). Agregar -dD dejará las definiciones también; y std = c89 se puede usar para ignorar el nuevo estilo // comentarios. Incluso con ellos, cpp reemplaza los comentarios con espacios (en lugar de eliminarlos) y contrae espacios y líneas vacías.
Pero creo que sigue siendo razonable y una solución fácil para la mayoría de los casos, si deshabilita la expansión de macros y otras cosas, creo que obtendrá buenos resultados ... y sí, puede combinar eso con el script de shell para mejorar ... y mucho más...
fuente
cpp
hará mucho más que eliminar comentarios (procesar#include
, expandir macros, incluidas las incorporadas ...)tail -n +7
solo eliminará las primeras 7 líneas, no evitará el#include
procesamiento o las expansiones de macros. Pruebaecho __LINE__ | cpp
por ejemplo. Oecho '#include /dev/zero' | cpp
-P
modo si haces esto. (Esto puede eliminar la necesidad de usartail
.)-fpreprocessed
deshabilitará la mayoría de las directivas y expansiones de macros (excepto#define
y#undef
aparentemente). Agregar-dD
dejará define también; ystd=c89
puede usarse para ignorar nuevos//
comentarios de estilo . Incluso con ellos,cpp
reemplaza los comentarios con espacios (en lugar de eliminarlos) y contrae espacios y líneas vacías.Una vez se me ocurrió esto que podemos refinar:
para manejar algunos casos más de esquina.
Tenga en cuenta que si elimina un comentario, podría cambiar el significado del código (
1-/* comment */-1
se analiza como1 - -1
while1--1
(que obtendría si eliminara el comentario) le daría un error). Es mejor reemplazar el comentario con un carácter de espacio (como lo hacemos aquí) en lugar de eliminarlo por completo.Lo anterior debería funcionar correctamente en este código ANSI C válido, por ejemplo, que intenta incluir algunos casos de esquina:
Lo que da esta salida:
Ambos imprimen el mismo resultado cuando se compilan y se ejecutan.
Puede comparar con la salida de
gcc -ansi -E
para ver qué haría el preprocesador en él. Ese código es también válido o código C99 C11, sin embargogcc
desactiva trigrafos apoyan de forma predeterminada por lo que no va a funcionar congcc
menos que especifique el estándar comogcc -std=c99
ogcc -std=c11
o agregar la-trigraphs
opción).También funciona en este código C99 / C11 (no ANSI / C90):
(comparar con
gcc -E
/gcc -std=c99 -E
/gcc -std=c11 -E
)ANSI C no apoyó el
// form
comentario.//
de lo contrario no es válido en ANSI C, por lo que no aparecería allí. Un caso artificial en el que//
puede aparecer genuinamente en ANSI C (como se señala allí , y puede encontrar interesante el resto de la discusión) es cuando el operador stringify está en uso.Este es un código ANSI C válido:
Y en el momento de la discusión en 2004, de
gcc -ansi -E
hecho lo expandió a"//not a comment"
. Sin embargo, hoygcc-5.4
devuelve un error, por lo que dudo que encontremos mucho código C con este tipo de construcción.El
sed
equivalente de GNU podría ser algo como:Si su GNU
sed
es demasiado antigua para admitir-E
o-z
, puede reemplazar la primera línea con:fuente
gcc -std=c11 -E -P
(-ansi
es solo otro nombre para-std=c90
).??'
), por lo tanto, comparamos concpp -ansi
aquellos y C99 / C11 ... one (like// xxx
), por lo tanto, comparamos concpp
(ocpp -std=c11
...)con
sed
:ACTUALIZAR
admite todo lo posible (comentarios de varias líneas, datos después de [o y] antes,);
correr:fuente
proc print data 2nd /*another comment is here*/
Elimine las líneas en blanco si las hay:
Editar - la versión más corta de Stephane:
fuente
-0777
como una forma más corta de hacerloBEGIN{$/=undef}
.*?
lugar de.+?
si/**/
es un comentario válido también.Solución mediante el comando SED y sin script
Aquí estás:
sed 's/\*\//\n&/g' test | sed '/\/\*/,/\*\//d'
Nota: Esto no funciona en OS X, a menos que lo instale
gnu-sed
. Pero funciona en Linux Distros.fuente
-i
opción para editar el archivo en el lugar en lugar de redirigir la salida al nuevo archivo. o mucho más seguro-i.bak
para el archivo de respaldosed
opera en una línea a la vez, pero algunos de los comentarios en la entrada abarcan varias líneas. Según /unix//a/152389/90751 , primero puede usartr
para convertir los saltos de línea en algún otro carácter. Luegosed
puede procesar la entrada como una sola línea, y puede usarlatr
nuevamente para restaurar los saltos de línea.He usado bytes nulos, pero puede elegir cualquier carácter que no aparezca en su archivo de entrada.
*
tiene un significado especial en las expresiones regulares, por lo que necesitará escapar\*
para que coincida con un literal*
..*
es codicioso : coincidirá con el texto más largo posible, incluyendo más*/
y/*
. Eso significa el primer comentario, el último comentario y todo lo demás. Para restringir esto, reemplace.*
con un patrón más estricto: los comentarios pueden contener cualquier cosa que no sea un "*", y también "*" seguido de cualquier cosa que no sea un "/". Las ejecuciones de múltiples*
s también deben tenerse en cuenta:Esto eliminará cualquier salto de línea en los comentarios multilínea, es decir.
se convertirá
Si esto no es lo que se quería,
sed
se le puede pedir que mantenga uno de los saltos de línea. Esto significa elegir un personaje de reemplazo de salto de línea que pueda coincidir.\f
No se garantiza que el carácter especial y el uso de una referencia inversa que puede no haber coincidido con nada funcionen como está previsto en todas lassed
implementaciones. (Confirmé que funciona en GNU sed 4.07 y 4.2.2.)fuente
test.sas
en el medio de la tubería allí, por lo quesed
lee directamente y el primerotr
no tiene ningún efecto. Necesitas usarcat test.sas | tr ...
usando una línea sed para eliminar comentarios:
fuente