Comentar varias líneas en un archivo por lotes de DOS

98

He escrito un enorme archivo por lotes de MS DOS. Para probar este archivo por lotes, necesito ejecutar solo algunas líneas y quiero ocultar / comentar el resto.

Tengo algunas líneas de comentarios existentes que comienzan con, ::por lo tanto, no puedo usar ::más, ya que mezclará todos los comentarios.

¿Como puedó resolver esté problema?

user219628
fuente

Respuestas:

182

Puede utilizar a gotopara omitir el código.

goto comment
...skip this...
:comment
pdubs
fuente
11
+1: ¡Es divertido usar "goto" para esto Y funciona!
rap-2-h
1
Creo que lo gracioso es que no hay una definición de comentario real en la línea de comando, simplemente no puedo aceptar REMlíneas como líneas de comentario, hace que la salida sea oscura
mkb
125

Si desea agregar REM al principio de cada línea en lugar de usar GOTO, puede usar Notepad ++ para hacerlo fácilmente siguiendo estos pasos:

  1. Seleccione el bloque de líneas
  2. presione Ctrl-Q

Repite los pasos para descomentar

cvacca
fuente
6
Buen consejo. lo hace mucho más limpio.
Venom
1
¡Vaya, no sabía que notepad ++ tiene una característica tan agradable! En realidad, realmente lo eché de menos porque estoy acostumbrado a 'Ctrl + 7' en Eclipse. Votado 42 ;)
Danny Lo
1
¿Qué hay de descomentar? Hay algún atajo para descomentar todo el bloque.
Bhaskar Singh
2
@BhaskarSingh A partir de Notepad ++ 7.5.6, simplemente puede resaltar el texto ya comentado; haga "Ctrl + Q", y lo descomentará
CreativiTimothy
Si el cerebro es a menudo débil como la mía para recordar Ctrl-Q, haga clic en Notepad++: Edit -> Comment/Uncomment.
Timo
13
break||(
 code that cannot contain non paired closing bracket
)

Si bien la gotosolución es una buena opción, no funcionará entre corchetes (incluidos los comandos FOR e IF), pero sí. Aunque debe tener cuidado con el cierre de corchetes y la sintaxis no válida para los comandos FORy IFporque se analizarán.

Actualizar

La actualización en la respuesta de dbenham me dio algunas ideas. Primero, hay dos casos diferentes en los que podemos necesitar comentarios de varias líneas, en un contexto de corchetes donde GOTO no se puede usar y fuera de él. Dentro de los paréntesis contexto se puede utilizar otros soportes si hay una condición que impide que el código sea executed.Though la Thede código todavía se analiza y se detectó algunos errores de sintaxis ( FOR, IF, soportes mal cerrados, la expansión de parámetros mal ..). Así si es posible, es mejor usar GOTO.

Aunque no es posible crear una macro / variable utilizada como etiqueta, pero es posible usar macros para los comentarios de corchetes. Sin embargo, se pueden usar dos trucos para hacer que los comentarios GOTO sean más simétricos y más agradables (al menos para mí). Para esto, usaré dos trucos: 1) puedes poner un solo símbolo delante de una etiqueta y goto aún podrá encontrarlo (no tengo idea de por qué es esto, mis amigos está buscando una unidad). 2) puede poner un solo : al final de un nombre de variable y no se activará una función de reemplazo / subcadena (incluso en las extensiones habilitadas). Lo que combinado con las macros para comentarios de corchetes puede hacer que ambos casos se vean casi iguales.

Así que aquí están los ejemplos (en el orden que más me gustan):

Con soportes rectangulares :

@echo off

::GOTO comment macro
set "[:=goto :]%%"
::brackets comment macros
set "[=rem/||(" & set "]=)"

::testing
echo not commented 1

%[:%
  multi 
  line
  comment outside of brackets
%:]%

echo not commented 2

%[:%
  second multi 
  line
  comment outside of brackets
%:]%

::GOTO macro cannot be used inside for
for %%a in (first second) do (
    echo first not commented line of the %%a execution
    %[%
        multi line
        comment
    %]%
    echo second not commented line of the %%a execution
)

Con llaves :

@echo off

::GOTO comment macro
set "{:=goto :}%%"
::brackets comment macros
set "{=rem/||(" & set "}=)"

::testing
echo not commented 1

%{:%
  multi 
  line
  comment outside of brackets
%:}%

echo not commented 2

%{:%
  second multi 
  line
  comment outside of brackets
%:}%

::GOTO macro cannot be used inside for loop
for %%a in (first second) do (
    echo first not commented line of the %%a execution
    %{%
        multi line
        comment
    %}%
    echo second not commented line of the %%a execution
)

Entre paréntesis :

@echo off

::GOTO comment macro
set "(:=goto :)%%"
::brackets comment macros
set "(=rem/||(" & set ")=)"

::testing
echo not commented 1

%(:%
  multi 
  line
  comment outside of brackets
%:)%

echo not commented 2

%(:%
  second multi 
  line
  comment outside of brackets
%:)%

::GOTO macro cannot be used inside for loop
for %%a in (first second) do (
    echo first not commented line of the %%a execution
    %(%
        multi line
        comment
    %)%
    echo second not commented line of the %%a execution
)

Mezcla entre los estilos PowerShell y C ( <no se puede usar porque la redirección es con mayor prioridad. *No se puede usar debido a %*):

@echo off

::GOTO comment macro
set "/#:=goto :#/%%"
::brackets comment macros
set "/#=rem/||(" & set "#/=)"

::testing
echo not commented 1

%/#:%
  multi 
  line
  comment outside of brackets
%:#/%

echo not commented 2

%/#:%
  second multi 
  line
  comment outside of brackets
%:#/%

::GOTO macro cannot be used inside for loop
for %%a in (first second) do (
    echo first not commented line of the %%a execution
    %/#%
        multi line
        comment
    %#/%
    echo second not commented line of the %%a execution
)

Para enfatizar que es un comentario (aunque no es tan corto):

@echo off

::GOTO comment macro
set "REM{:=goto :}REM%%"
::brackets comment macros
set "REM{=rem/||(" & set "}REM=)"

::testing
echo not commented 1

%REM{:%
  multi 
  line
  comment outside of brackets
%:}REM%

echo not commented 2

%REM{:%
  second multi 
  line
  comment outside of brackets
%:}REM%

::GOTO macro cannot be used inside for
for %%a in (first second) do (
    echo first not commented line of the %%a execution
    %REM{%
        multi line
        comment
    %}REM%
    echo second not commented line of the %%a execution
)
npocmaka
fuente
1
Podrías usar rem.||(o en su rem^ (lugar. La intención es un poco más clara. Vea mi respuesta actualizada.
dbenham
@dbenham - sí, con rem es más corto.
npocmaka
1
Oh, las formas de corchetes cuadrados y rizados son sexys. Si estuviera escribiendo código solo para mí, podría usarlo. Pero imagino que el usuario promedio vería eso y diría WTF.
dbenham
@dbenham - puede ser que tengas razón. También puedo incluir el formulario %rem:%+ %:rem%para hacerlo más obvio, aunque perderá su encanto. O solo barra para estar más cerca del estilo C ...
npocmaka
1
@npocmaka ¡Esto es increíble! Acabo de aprender un montón de complejidades de secuencias de comandos por lotes mientras averiguaba lo que hiciste. De todos los métodos de comentarios en bloque que conozco (por lotes), este parece ser el más robusto e inteligente. +1 por combinar truco y estilo
Jared Gotte
10

Otra opción es encerrar las líneas no deseadas en un bloque IF que nunca puede ser cierto

if 1==0 (
...
)

Por supuesto, no se ejecutará nada dentro del bloque if, pero se analizará. Por lo que no puede tener una sintaxis inválida dentro. Además, el comentario no puede contener a )menos que sea de escape o citado. Por esas razones, la solución GOTO aceptada es más confiable. (La solución GOTO también puede ser más rápida)

Actualización 2017-09-19

Aquí hay una mejora cosmética de la solución GOTO de pdub . Defino una variable de entorno simple "macro" que hace que la sintaxis del comentario GOTO sea un poco mejor autodocumentada. Aunque generalmente se recomienda que: las etiquetas sean únicas dentro de un script por lotes, realmente está bien incrustar varios comentarios como este dentro del mismo script por lotes.

@echo off
setlocal

set "beginComment=goto :endComment"

%beginComment%
Multi-line comment 1
goes here
:endComment

echo This code executes

%beginComment%
Multi-line comment 2
goes here
:endComment

echo Done

O puede usar una de estas variantes de la solución de npocmaka . El uso de REM en lugar de BREAK hace que la intención sea un poco más clara.

rem.||(
   remarks
   go here
)

rem^ ||(
   The space after the caret
   is critical
)
dbenham
fuente
1

Solo quiero mencionar que la solución GOTO de pdub no es completamente correcta en caso de que: la etiqueta de comentario aparezca varias veces. Modifico el código de esta pregunta como ejemplo.

@ECHO OFF
SET FLAG=1
IF [%FLAG%]==[1] (
    ECHO IN THE FIRST IF...
    GOTO comment
    ECHO "COMMENT PART 1"
:comment
    ECHO HERE AT TD_NEXT IN THE FIRST BLOCK
)

IF [%FLAG%]==[1] (
    ECHO IN THE SECOND IF...
    GOTO comment
    ECHO "COMMENT PART"
:comment
    ECHO HERE AT TD_NEXT IN THE SECOND BLOCK
)

La salida será

IN THE FIRST IF...
HERE AT TD_NEXT IN THE SECOND BLOCK

Se omite el comando ECHO AQUÍ EN TD_NEXT EN EL PRIMER BLOQUE .

Charles Chiou
fuente
0

@jeb

Y después de usar esto, el stderr parece ser inaccesible

No, intente esto:

@echo off 2>Nul 3>Nul 4>Nul

   ben ali  
   mubarak 2>&1
   gadeffi
   ..next ?

   echo hello Tunisia

  pause

¿Pero por qué funciona?

lo siento, contesto la pregunta en francés:

(la redirection par 3> est spécial car elle persiste, on va l'utiliser pour capturer le flux des erreurs 2> est on va le transformer en un flux persistant à l'ade de 3> ceci va nous permettre d'avoir une gestion des erreur pour tout notre environement de script..par la suite si on veux recuperer le flux 'stderr' il faut faire une autre redirection du handle 2> au handle 1> qui n'est autre que la console ..)

walid2mi
fuente
1
No puedo leer en francés, pero no parece que menciones por qué el flujo 2 (stderr) continúa deshabilitado después de que finaliza la redirección inicial. Tengo una teoría viable y casos de prueba en 2 publicaciones consecutivas en dostips.com/forum/viewtopic.php?p=14612#p14612 .
dbenham
(La redirección por 3> es especial porque persiste, la usaremos para capturar el flujo de errores 2> si la convertirá en un flujo persistente a ade de 3> esto nos permitirá tener un error de gestión para cualquiera de nuestras script de entorno ... entonces si desea recuperar el flujo 'stderr' debemos hacer otro redireccionamiento de manejador 2> para manejar un> que no es otro que la consola ..)
user96403
-1

prueba esto:

   @echo off 2>Nul 3>Nul 4>Nul

   ben ali
   mubarak
   gadeffi
   ..next ?

   echo hello Tunisia

  pause
walid2mi
fuente
+1, pero ¿por qué funciona? Y después de usar esto, el stderr parece ser inaccesible
jeb
1
-1, Esto "funciona" porque echo 2> Nul está redirigiendo el flujo de error estándar a NUL, enterrándolo (el 3> Nul, 4> Nul están redirigiendo flujos auxiliares sin una razón real). Esto no comenta las líneas, simplemente evita que se muestren mensajes de error. Por lo tanto, todo lo que pueda interpretarse como líneas de comando se seguirá ejecutando.
pdubs
3
El comentario de pdubs es parcialmente correcto porque los comandos aún se están ejecutando (y fallan porque no son válidos). Pero los comandos válidos se ejecutarían sin fallas. Por tanto, esta no es una buena solución para comentar líneas de código. La explicación de por qué el flujo 2 (stderr) está deshabilitado "permanentemente" no es correcta.
dbenham
3
Tengo una teoría sobre cómo funciona la redirección en lotes de Windows, y explica por qué stderr se desactiva "permanentemente" en esta respuesta. La teoría y las pruebas están en 2 publicaciones consecutivas en dostips.com/forum/viewtopic.php?p=14612#p14612
dbenham