Komentowanie wielu wierszy w pliku wsadowym DOS


98

Napisałem ogromny plik wsadowy MS DOS. Aby przetestować ten plik wsadowy, muszę wykonać tylko niektóre wiersze i chcę ukryć / skomentować pozostałe.

Mam kilka istniejących linii komentarzy zaczynających się od, ::dlatego nie mogę ich ::już używać, ponieważ spowoduje to pomieszanie wszystkich komentarzy.

Jak mogę rozwiązać ten problem?

Odpowiedzi:


184

Możesz użyć gotodo pominięcia kodu.

goto comment
...skip this...
:comment

11
+1: Zabawnie jest używać do tego „goto” I to działa!
rap-2-h

1
Myślę, że zabawne jest to, że nie ma prawdziwej definicji komentarza w wierszu poleceń, po prostu nie mogę zaakceptować REMwierszy jako wierszy komentarzy, to sprawia, że ​​dane wyjściowe są niejasne
mkb

126

Jeśli chcesz dodać REM na początku każdej linii zamiast używać GOTO, możesz użyć Notepad ++, aby zrobić to łatwo, wykonując następujące kroki:

  1. Wybierz blok linii
  2. naciśnij Ctrl-Q

Powtórz kroki, aby odkomentować


6
Niezła wskazówka. sprawia, że ​​jest znacznie czystszy.
Venom

1
Wow, nie wiedziałem, że Notatnik ++ ma taką fajną funkcję! Właściwie to naprawdę to przegapiłem, ponieważ jestem przyzwyczajony do Ctrl + 7 w Eclipse. Zagłosowano do 42 ;)
Danny Lo

1
A co z brakiem komentarzy. Tam jest jakikolwiek skrót do odkomentowania całego bloku.
Bhaskar Singh,

2
@BhaskarSingh Począwszy od Notepad ++ 7.5.6, możesz po prostu zaznaczyć już skomentowany tekst; wykonaj „Ctrl + Q”, a odkomentuje to
CreativiTimothy

Jeśli twój mózg jest często słaby jak kopalnia pamiętać Ctrl-Q, kliknij Notepad++: Edit -> Comment/Uncomment.
Timo

13
break||(
 code that cannot contain non paired closing bracket
)

Chociaż gotorozwiązanie jest dobrą opcją, nie będzie działać w nawiasach kwadratowych (łącznie z poleceniami FOR i IF), ale tak będzie. Chociaż powinieneś uważać na zamykające nawiasy i nieprawidłową składnię poleceń FORi IF, ponieważ zostaną one przeanalizowane.

Aktualizacja

Aktualizacja w odpowiedzi dbenham dała mi kilka pomysłów. Po pierwsze - istnieją dwa różne przypadki, w których możemy potrzebować komentarzy wieloliniowych - w kontekście nawiasów, gdzie nie można użyć GOTO i poza nim. Kontekst nawiasach możemy użyć innego wsporniki jeśli jest to warunek, który zapobiega kod będzie executed.Though Thede kod nadal będą przetwarzane i zostaną wykryte jakieś błędy składniowe ( FOR, IF, wsporniki nieprawidłowo zamknięte, niewłaściwy parametr ekspansja ..). So jeśli to możliwe, lepiej użyć GOTO.

Chociaż nie jest możliwe utworzenie makra / zmiennej używanej jako etykieta - ale jest możliwe użycie makr do komentarzy w nawiasach, jednak można zastosować dwie sztuczki, aby komentarze GOTO były bardziej symetryczne i przyjemniejsze (przynajmniej dla mnie). W tym celu wykorzystam dwie sztuczki - 1) możesz umieścić pojedynczy symbol przed etykietą, a goto nadal będzie w stanie go znaleźć (nie mam pojęcia, dlaczego tak się dzieje, sądzę, że szuka dysku). 2) możesz umieścić pojedynczą wartość : na końcu nazwy zmiennej, a funkcja zastępowania / podciągania nie zostanie uruchomiona (nawet pod włączonymi rozszerzeniami). To w połączeniu z makrami komentarzy w nawiasach może sprawić, że oba przypadki będą wyglądać prawie tak samo.

Oto przykłady (w kolejności, w której najbardziej je lubię):

Z prostokątnymi wspornikami :

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

Z nawiasami klamrowymi :

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

Z nawiasami :

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

Mieszanka między stylami PowerShell i C ( <nie można jej użyć, ponieważ przekierowanie ma wyższy priorytet. *Nie można jej użyć z powodu %*):

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

Aby podkreślić , to jest komentarz (myślę, że nie jest taki krótki):

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

1
Możesz użyć rem.||(lub rem^ (zamiast tego. Zamiar jest nieco jaśniejszy. Zobacz moją zaktualizowaną odpowiedź.
dbenham

@dbenham - tak, z rem jest krótszy.
npocmaka

1
Ooh, kwadratowe i nawiasy klamrowe są seksowne. Gdybym pisał kod tylko dla siebie, mógłbym go użyć. Ale wyobrażam sobie, że przeciętny użytkownik to zobaczy i powie WTF.
dbenham

@dbenham - może masz rację, mogę też dodać %rem:%+ %:rem%formę, żeby było to bardziej oczywiste, choć straci swój urok lub tylko ukośnik, aby być bliżej stylu C ...
npocmaka

1
@npocmaka To jest niesamowite! Właśnie dowiedziałem się kilku zawiłości skryptów wsadowych, zastanawiając się, co zrobiłeś. Ze wszystkich znanych mi metod komentarzy blokowych (dla partii), ta wydaje się być najbardziej niezawodna i sprytna. +1 za połączenie hackowania i stylu
Jared Gotte

10

Inną opcją jest umieszczenie niechcianych wierszy w bloku IF, który nigdy nie może być prawdziwy

if 1==0 (
...
)

Oczywiście nic w bloku if nie zostanie wykonane, ale zostanie przeanalizowane. Więc nie możesz mieć w nim nieprawidłowej składni. Ponadto komentarz nie może zawierać )znaków, o ile nie jest poprzedzony znakami ucieczki lub cudzysłowem. Z tych powodów przyjęte rozwiązanie GOTO jest bardziej niezawodne. (Rozwiązanie GOTO może być również szybsze)

Aktualizacja 2017-09-19

Oto kosmetyczne ulepszenie rozwiązania GOTO firmy pdub . Definiuję prostą zmienną środowiskową „makro”, która sprawia, że ​​składnia komentarzy GOTO jest nieco lepsza samodokumentująca. Chociaż generalnie zaleca się, aby: etykiety były unikalne w skrypcie wsadowym, naprawdę można osadzić wiele takich komentarzy w tym samym skrypcie wsadowym.

@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

Lub możesz użyć jednego z tych wariantów rozwiązania npocmaki . Użycie REM zamiast BREAK sprawia, że ​​intencja jest nieco jaśniejsza.

rem.||(
   remarks
   go here
)

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

1

Chcę tylko wspomnieć, że rozwiązanie GOTO pdub nie jest w pełni poprawne w przypadku: etykieta komentarza pojawia się wielokrotnie. Jako przykład modyfikuję kod z tego pytania .

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

Wynik będzie

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

Polecenie ECHO TUTAJ W TD_NEXT W PIERWSZYM BLOKU jest pomijane.


0

@jeb

Po użyciu tego stderr wydaje się być niedostępny

Nie, spróbuj tego:

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

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

   echo hello Tunisia

  pause

Ale dlaczego to działa?

przepraszam, odpowiadam na pytanie w języku 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 transformer 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 ..)


1
Nie mogę czytać po francusku, ale wygląda na to, że nie rozwiązujesz problemu, dlaczego strumień 2 (stderr) jest nadal wyłączony po zakończeniu początkowego przekierowania. Mam praktyczną teorię i przypadki testowe w 2 kolejnych postach pod adresem dostips.com/forum/viewtopic.php?p=14612#p14612 .
dbenham

(Przekierowanie przez 3> jest wyjątkowe, ponieważ utrzymuje się, użyjemy go do przechwycenia przepływu błędów 2> czy zmieni go w trwały przepływ do 3> pozwoli nam to na błąd zarządzania dla każdego z naszych skrypt środowiska .. wtedy jeśli chcesz odzyskać przepływ „stderr”, musimy wykonać inne przekierowanie uchwytu 2>, aby obsłużyć>, które jest niczym innym jak konsolą ..)
user96403

-1

Spróbuj tego:

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

   ben ali
   mubarak
   gadeffi
   ..next ?

   echo hello Tunisia

  pause

+1, ale dlaczego to działa? Po użyciu tego, stderr wydaje się być niedostępny
jeb

1
-1, To "działa", ponieważ echo 2> Nul przekierowuje standardowy strumień błędów do NUL, zakopując go (3> Nul, 4> Nul przekierowują strumienie pomocnicze bez żadnego powodu). Nie powoduje to komentowania wierszy, a jedynie zapobiega wyświetlaniu komunikatów o błędach. Więc wszystko, co można zinterpretować jako wiersze poleceń, nadal będzie działać.
pdubs

3
Komentarz pdubs jest częściowo poprawny, ponieważ polecenia nadal są wykonywane (i kończą się niepowodzeniem, ponieważ są nieprawidłowe). Ale prawidłowe polecenia byłyby wykonywane bezbłędnie. Nie jest to więc dobre rozwiązanie do komentowania linii kodu. Wyjaśnienie, dlaczego strumień 2 (stderr) jest „na stałe” wyłączony, jest nieprawidłowe.
dbenham

3
Mam teorię dotyczącą działania przekierowania w systemie Windows i wyjaśnia, dlaczego stderr zostaje „na stałe” wyłączony w tej odpowiedzi. Teoria i testy znajdują się w 2 kolejnych postach pod adresem dostips.com/forum/viewtopic.php?p=14612#p14612
dbenham
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.