Comentando várias linhas no arquivo de lote DOS

98

Eu escrevi um arquivo Batch enorme do MS DOS. Para testar este arquivo em lote, preciso executar apenas algumas linhas e quero ocultar / comentar o restante.

Eu tenho algumas linhas de comentários começando com, ::portanto, não posso usar ::mais, pois isso embaralhará todos os comentários.

Como posso resolver esse problema?

user219628
fonte

Respostas:

182

Você pode usar um gotopara pular o código.

goto comment
...skip this...
:comment
pdubs
fonte
11
+1: É engraçado usar "goto" para isso E funciona!
rap-2-h
1
Acho que o que é engraçado é que não há uma definição real de comentário na linha de comando, eu simplesmente não posso aceitar REMlinhas como linhas de comentário, isso torna a saída obscura
mkb
125

Se desejar adicionar REM no início de cada linha em vez de usar GOTO, você pode usar o Notepad ++ para fazer isso facilmente seguindo estas etapas:

  1. Selecione o bloco de linhas
  2. pressione Ctrl-Q

Repita as etapas para descomentar

cvacca
fonte
6
Boa dica. torna muito mais limpo.
Venom de
1
Nossa, não sabia que o notepad ++ tem um recurso tão legal! Na verdade, realmente perdi porque estou acostumado a `Ctrl + 7 'no Eclipse. Votado até 42 ;)
Danny Lo
1
Que tal descomentar. Lá existe qualquer atalho para descomentar todo o bloco.
Bhaskar Singh
2
@BhaskarSingh A partir do Notepad ++ 7.5.6, você pode simplesmente destacar o texto já comentado; faça "Ctrl + Q", e ele removerá o comentário
CreativiTimothy
Se seu cérebro é muitas vezes fraco como o meu para lembrar Ctrl-Q, clique em Notepad++: Edit -> Comment/Uncomment.
Timo de
13
break||(
 code that cannot contain non paired closing bracket
)

Embora a gotosolução seja uma boa opção, ela não funcionará entre colchetes (incluindo os comandos FOR e IF). Mas funcionará. No entanto, você deve ter cuidado ao fechar colchetes e sintaxe inválida para comandos FORe IFporque eles serão analisados.

Atualizar

A atualização na resposta do dbenham me deu algumas idéias. Primeiro - há dois casos diferentes em que podemos precisar de comentários de várias linhas - em um contexto de colchetes onde GOTO não pode ser usado e fora dele. Dentro de colchetes de contexto, pode usar outro parêntesis, se há uma condição que impede que o código a ser executed.Though o Thede código ainda será analisado e alguns erros de sintaxe será detectado ( FOR, IF, suportes indevidamente fechadas, expansão de parâmetros errado ..). Assim, se for possível, é melhor usar GOTO.

Embora não seja possível criar uma macro / variável usada como um rótulo - mas é possível usar macros para comentários de colchetes. Ainda assim, dois truques podem ser usados ​​para tornar os comentários GOTO mais simétricos e mais agradáveis ​​(pelo menos para mim). Para isso, usarei dois truques - 1) você pode colocar um único símbolo na frente de uma etiqueta e goto ainda será capaz de encontrá-lo (não tenho ideia do motivo disso. Meu palpite é que ele está procurando uma unidade). 2) você pode colocar um único : no final de um nome de variável e um recurso de substituição / subtração não será acionado (mesmo em extensões habilitadas). O que combinado com as macros para comentários de colchetes pode fazer com que os dois casos pareçam quase iguais.

Então, aqui estão os exemplos (na ordem em que mais gosto):

Com colchetes retangulares :

@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
)

Com chaves :

@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
)

Com parênteses :

@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
)

Mistura entre os estilos PowerShell e C ( <não pode ser usado porque o redirecionamento é com prio superior. *Não pode ser usado por causa do %*):

@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 é um comentário (embora não seja tão curto):

@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
fonte
1
Você pode usar rem.||(ou em rem^ (vez disso. A intenção é um pouco mais clara. Veja minha resposta atualizada.
dbenham
@dbenham - sim com rem é mais curto.
npocmaka de
1
Ooh, as formas dos colchetes são sexy. Se eu estivesse escrevendo código apenas para mim, poderia usá-lo. Mas imagino que o usuário médio veria isso e diria WTF.
dbenham
@dbenham - pode ser que você esteja certo.Eu posso incluir o formulário %rem:%+ %:rem%também para torná-lo mais óbvio, embora ele perca seu charme.Ou apenas barra para ficar mais perto do estilo C ...
npocmaka
1
@npocmaka Isso é incrível! Acabei de aprender um monte de complexidades de scripting em lote enquanto descobria o que você fazia. De todos os métodos de comentários em bloco que conheço (para lote), este parece ser o mais robusto e inteligente. +1 para combinar hack e estilo
Jared Gotte
10

Outra opção é colocar as linhas indesejadas em um bloco IF que nunca pode ser verdadeiro

if 1==0 (
...
)

É claro que nada dentro do bloco if será executado, mas será analisado. Portanto, você não pode ter nenhuma sintaxe inválida dentro. Além disso, o comentário não pode conter, a )menos que seja escapado ou entre aspas. Por essas razões, a solução GOTO aceita é mais confiável. (A solução GOTO também pode ser mais rápida)

Atualização 19/09/2017

Aqui está uma melhoria cosmética para a solução GOTO da pdub . Eu defino uma variável de ambiente simples "macro" que torna a sintaxe do comentário GOTO um pouco melhor autodocumentada. Embora seja geralmente recomendado que: os rótulos sejam exclusivos em um script de lote, realmente não há problema em incorporar vários comentários como esse no mesmo script de lote.

@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

Ou você pode usar uma dessas variantes da solução de npocmaka . O uso de REM em vez de BREAK torna a intenção um pouco mais clara.

rem.||(
   remarks
   go here
)

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

Só quero mencionar que a solução GOTO do pdub não é totalmente correta no caso: o rótulo do comentário aparecer várias vezes. Eu modifico o código desta questão como exemplo.

@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
)

A saída será

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

O comando ECHO HERE AT TD_NEXT NO PRIMEIRO BLOCO é ignorado.

Charles Chiou
fonte
0

@jeb

E depois de usar isso, o stderr parece estar inacessível

Não, tente isto:

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

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

   echo hello Tunisia

  pause

Mas porque funciona?

desculpe, eu respondo a pergunta em frensh:

(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 transformador en un flux persistant à l'ade de 3> ceci va nous permettre d'avoir une gestion des erreur pour tout notre Environment 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
fonte
1
Não consigo ler em francês, mas parece que você não explica por que o fluxo 2 (stderr) continua a ser desabilitado após o término do redirecionamento inicial. Eu tenho uma teoria viável e casos de teste em 2 posts consecutivos em dostips.com/forum/viewtopic.php?p=14612#p14612 .
dbenham
(Redirecionamento por 3> é especial porque persiste, vamos usá-lo para capturar o fluxo de erros 2> se ele irá transformá-lo em um fluxo persistente para ade de 3> isso nos permitirá ter um erro de gerenciamento para qualquer um de nossos script de ambiente .. então se você quiser recuperar o fluxo 'stderr', devemos fazer outro redirecionamento de identificador 2> para manipular um> que não é outro senão o console ..)
user96403
-1

tente isto:

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

   ben ali
   mubarak
   gadeffi
   ..next ?

   echo hello Tunisia

  pause
walid2mi
fonte
1, mas por que funciona? E depois de usar isso, o stderr parece ser inacessível
jeb
1
-1, Isso "funciona" porque o echo 2> Nul está redirecionando o fluxo de erro padrão para o NUL, enterrando-o (os 3> Nul, 4> Nul estão redirecionando os fluxos auxiliares sem motivo real). Isso não comenta as linhas, apenas impede a exibição de mensagens de erro. Portanto, qualquer coisa que possa ser interpretada como linhas de comando ainda será executada.
pdubs
3
O comentário de pdubs está parcialmente correto porque os comandos ainda estão em execução (e falhando porque não são válidos). Mas os comandos válidos seriam executados sem falha. Portanto, esta não é uma boa solução para comentar linhas de código. A explicação de por que o fluxo 2 (stderr) está "permanentemente" desabilitado não está correta.
dbenham
3
Eu tenho uma teoria sobre como o redirecionamento funciona no lote do Windows e isso explica por que stderr se torna "permanentemente" desabilitado nesta resposta. A teoria e os testes estão em 2 postagens consecutivas em dostips.com/forum/viewtopic.php?p=14612#p14612
dbenham