Why does this batch file fail on a "REM" line?
Solution 1
The error-msg refers to the commented out second line
This is due to the very complex parsing that is used by cmd
to process scripts.
In short the parser processes %
before pretty much everything else (phase 1) and throws an error as some of the %
s need to be doubled as %%
when used in a batch file.
So in a batch file:
for %%F in (*.pdf) do ren "%%~F" "%%~nF OdB%%~xF"
is a valid command and:
REM for %a in (*.txt) do ren "%~a" "%~na version 1%~xa"
is a broken command (the %a
should be %%a
, etc).
Note that:
REM for %a in (*.txt) do ren "%~a" "%~na version 1%~xa"
is a valid command when run from the command line as then the %
does not need to be doubled.
REM
would be processed in phase 2 of the parser, but it never gets there as the %
processing in phase 1 has already generated an error and terminated the parsing.
For all the gory details of the cmd
parser please read parsing - How does the Windows Command Interpreter (CMD.EXE) parse scripts? - Stack Overflow
Solution 2
It doesn't work because even though it is "remarked" it is evaluated for substitutions, and then apparently discarded.
For "batch" your second line is incorrect and should read
REM Rework 2020-12-16
REM for %%a in (*.txt) do ren "%%~a" "%%~na version 1%%~xa"
for %%F in (*.pdf) do ren "%%~F" "%%~nF OdB%%~xF"
The corrections being that in batch programming expansions need to have %% rather than a single %.
Solution 3
To add to the existing answers, although REM
is used for comments, it is important to understand that it is actually a command that does nothing, not a comment. This is different from a Unix shell, where you have real comments and can add arbitrary text after a #
character.
Not only the substitutes are evaluated for the REM
command, also file redirects. So beware that the following line will delete the content of the file, because the REM
command produces no output, but the empty output will be redirected to the file
REM some_command > important_file
Edit
As a comment pointed out, this is no longer true for modern Windows versions. According to https://stackoverflow.com/a/4095133/10765659 there is now special handling of REM
so that redirections are not executed, but this special handling occurs too late to make REM
a true comment, as the substitutes are still evaluated.
Related videos on Youtube
gkln
Updated on September 18, 2022Comments
-
gkln over 1 year
I refer to question Add text to end of filename (but before extension) using batch file as I have the same problem. Using Windows 7 32-bit Enterprise (I know, I know ...) with all updates I wrote a tiny batch file
pdfrename.bat
with only three lines:-
a comment, starting with
REM
and no "hidden" continuation sign more to the right of the line -
the proposed command, copy-pasted from the source as provided by @Karan, commented out with
REM
-
the adopted command for batch (doubling the
%
):REM Rework 2020-12-16 REM for %a in (*.txt) do ren "%~a" "%~na version 1%~xa" for %%F in (*.pdf) do ren "%%~F" "%%~nF OdB%%~xF"
Running the command (3.) from the command-prompt,
for %F in (*.pdf) do ren "%~F" "%~nF OdB%~xF"
works fine.
But executing the whole batch-file
pdfrename.bat
from Windows explorer fails. Running the batch file from the command promptpdfrename.bat
produces an error message syntax error:Die folgende Verwendung des Pfadoperators zur Ersetzung eines Batchparameters ist ungültig: %~na version 1%~xa" [...]
You need not to understand German. The important point is that the error message refers to the commented out second line (2.), not to the third line!
I tried to retype
REM
, inserted a tabulator after REM, inserted a secondREM
after the first (REM REM ....
), inserted a third line after the second one with the same content and deleted the second line afterwards - nothing changed: the batch file terminates at the commented out second line with a syntax error. As soon as the incriminated second line is eliminated from the batch, the batch works fine.I searched for "REM is ignored", but no luck, so I post the matter here. I never heard about or experienced before that the command processor tries at least to analyze a commented out line - and in the case that there is something wrong with the code after the comment-sign that it terminates the batch script.
-
Christoffer Hammarström over 3 years
-
Olivier Dulac over 3 yearsa workaround: if you wanted to provide an exemple: change this to say something like:
REM to do the same in a command prompt, divide the number of variable calls, for ex: %%f , by two. ie, only have 1 percent sign instead of 2
-
-
Mokubai over 3 yearsTechnically the
for %a in (*.txt) do ren "%~a" "%~na version 1%~xa"
is correct so long as it's not in a batch file itself. :) -
gkln over 3 years@DavidPostill with other words "works as designed" - but not as described in tutorials. Even herer docs.microsoft.com/en-us/windows-server/administration/…
-
Kamil Maciorowski over 3 yearsHave you tested the alleged redirection issue? How exactly? In what OS? My tests (in Win 7 so far) don't confirm the issue, the content of
important_file
survives. This other answer statesREM
is special in phase 2 and "treated dramatically different". It seems what I observed confirms the other answer, not yours. -
Euro Micelli over 3 yearsAnother way to look at it: don’t think of REM as a comment, but as an internal command that does nothing with its arguments.
-
Ruslan over 3 years@EuroMicelli it's quite similar to the
true
or:
command in Unixes, but working only inside batch scripts. -
nerkn over 3 yearsThere are also labels in batch scripts, which are written as
::
and are also often used as comments: <stackoverflow.com/questions/16632524/…> -
RalfFriedl over 3 years@KamilMaciorowski I didn't test this recently. A colleague had this problem in the time of early Windows, probably around or before Windows 95, and I avoided that ever since. I'm glad to hear that it has been fixed.
-
DavidPostill over 3 years@gkln Do you need more help? If this answered your question, please don't forget to accept the answer by clicking the accept button (the tick ✓ button). Also see Why is voting important?
-
Andrew Ray over 3 yearsBatch labels actually start with only a single
:
. A label written as::label
actually defines a label called:label
. It is safe to use this as a pseudo-comment, however, becauseGOTO :
has special handling for things likeGOTO :EOF
, so it's impossible to accidentally jump to a label that starts with a colon. -
karan punjabi over 3 yearsWow, this just blew my mind. The CMD parser processes text before acknowledging it's just a comment. Just... WOW.
-
Scott - Слава Україні over 3 yearsI was going to upvote this post for actually answering the question better than any of the other answers. But then I saw that, after seeing a comment pointing out an error in your post, you acknowledged it in another comment but you didn't edit the answer.
-
gkln over 3 years@Massimo Thanks!