¿Cómo puedo comentar / en una sección en el código fuente con sed o awk

Actualmente tengo archivos, que contienen secciones como esta

code statement1 code statement2 # BEGIN SOMENAME some code some other code # END SOMENAME code statement n +1 code statement n +1 

Lo que quiero hacer es comentar lo que hay entre «# BEGIN SOMENAME» y «# END», para que al final se vea así

code statement1 code statement2 # BEGIN SOMENAME # some code # some other code # END SOMENAME code statement n +1 code statement n +1 

¿Puedo lograr esto con awk o sed? y ¿puedo revertirlo fácilmente ?, así que solo una operación, ¿que «comenta» de nuevo?

Lo que quiero evitar es cometer errores, por lo que si las líneas ya están comentadas, debe dejarse solo. También en «comentar en» no debería intentar hacer algo si las líneas entre el final y el comienzo no comienzan con un «#».

Lo intenté ahora durante varias horas, sin éxito.

Encontré una posible solución:

awk " BEGIN { i=0; line_with_no_comment_found=0 } /^# END/ { m=0; if ( line_with_no_comment_found == 1 ) { for (var in a) print "# "a[var] } else { for (var in a) print a[var] } delete a; i=0; line_with_no_comment_found=0; } /^# / { if (m==0) { print } else { a[i++]=$0; } } !/^# / { if (m==0) { print } else { a[i++]=$0; line_with_no_comment_found=1} } /^# BEGIN ([a-zA-Z_])([1-9][0-9]*)*/ {m=1;} END { } "<<EOF 

Comentarios

  • tal vez, porque este código antiguo tiene errores como ese, múltiples líneas de inicio (¿copiar / pegar errores …?) después de otro, y solo necesita ignorar el primero o en algún momento el comienzo comienza y el archivo termina … i ' Prefiero no publicar este script, ahora está roto en la competencia ….
  • tienes razón. agregó esto a los desafíos. Lo siento, me cansé, y parece que siempre que encuentro una solución parcial, todas las demás cosas dejan de funcionar

Responder

Este script me funciona. Lo probé en GNU Awk 4.0.1, pero debería funcionar también en Nawk.

awk "BEGIN { # action=0: uncomment # action=1: comment action=0 in_optional_code_block=0 } { if ($0 ~ /^# BEGIN/) { in_optional_code_block=1 } else if ($0 ~ /^# END/) { in_optional_code_block=0 } else if (in_optional_code_block) { if (action) { if ($0 !~ /^#/) { $0 = "# " $0 } } else { if ($0 ~ /^#/) { sub(/^# ?/, "") } } } } 1" 

También escribí un pequeño script de shell adjunto:

#!/usr/bin/env sh syntax_error() { echo "Usage: `basename \"$0\"` [comment|uncomment] file" >&2 exit 1 } case "$1" in 0|uncomment) action=0; ;; 1|comment) action=1; ;; *) syntax_error; ;; esac shift if [ -z "$@" ]; then syntax_error; fi awk "BEGIN { action="$action" in_optional_code_block=0 } { if ($0 ~ /^# BEGIN/) { in_optional_code_block=1 } else if ($0 ~ /^# END/) { in_optional_code_block=0 } else if (in_optional_code_block) { if (action) { if ($0 !~ /^#/) { $0 = "# " $0 } } else { if ($0 ~ /^#/) { sub(/^# ?/, "") } } } } 1" "$@" > "[email protected]" if [ $? -eq 0 ]; then mv "[email protected]" "$@"; fi 

(Si tiene GNU Awk 4.1.0 o posterior, puede usar el indicador -i en lugar de la construcción de movimiento al final).

Comentarios

  • @Mandragor Si SOMENAME en los comentarios de apertura y cierre tienen que coincidir, dame un grito.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *