Batch file forfiles语法问题-如何与变量一起使用

Batch file forfiles语法问题-如何与变量一起使用,batch-file,syntax,Batch File,Syntax,我在这里搜索了一段时间,但找不出FORFILES的正确语法 REM here i want to give a unique name to the temp folder FOR /F "tokens=1-8 delims=:./" %%G IN ("%date%_%time%") DO ( SET dt=%%G%%H%%I_%%J_%%K ) echo %dt% 这是完整的代码 @echo on REM WHAT IS THIS FOR? REM i create word files o

我在这里搜索了一段时间,但找不出FORFILES的正确语法

REM here i want to give a unique name to the temp folder
FOR /F "tokens=1-8 delims=:./" %%G IN ("%date%_%time%") DO (
SET dt=%%G%%H%%I_%%J_%%K
)
echo %dt%
这是完整的代码

@echo on
REM WHAT IS THIS FOR?
REM i create word files on a remote shared folder. i need to move them to a 
REM local folder. Also i need to make PDF of them. if the files exist, 
REM i need to rename them like xx-R1, xx-R2 etc. up to R50 only. 
REM So this script first makes a temp folder and moves the word 
REM files there and renames them. In that temporary folder it makes 
REM pdf of the word files and then moves to the targeted folder. 
REM then must delete the temp folder. IT WORKS. I ve tried to make 
REM everything as a variable for people to benefit from it. Also you need to 
REM have the the JavaScript code called SAVEASPD.js. below i added the code 
REM i use for your reference. ONLY 1 for loop i couldnt manage below.

REM here i want to give a unique name to the temp folder
FOR /F "tokens=1-8 delims=:./" %%G IN ("%date%_%time%") DO (
SET dt=%%G%%H%%I_%%J_%%K
)
echo %dt%

REM create and set temp folder
mkdir "%SourceDir%\temp%dt%"
SET "TempDir=%SourceDir%\temp%dt%"

REM setting source folder:
SET "SourceDir=D:\TEST"

REM setting target folder
SET "TargetDir=D:\TEST\1"

REM listing criteria
SET "LIST=*.doc"

REM SAVEASPDF.js location
SET "JSLOC=D:\TEST"

REM ready to go...

FOR /F "usebackq delims=;" %%I IN ('DIR %SourceDir%\%LIST% /b') DO (
    IF NOT EXIST "%TargetDir%\%%~nxI" (
        CALL :MOVEFILEFUNCTION "%%I"
    ) ELSE (
        CALL :RENAMEFUNCTION "%%I"
    )
)
GOTO:FINISHING
GOTO:EOF

:MOVEFILEFUNCTION
move %1 "%TempDir%"
REM HOW TO MAKE this LOOP ??
for /f "usebackq delims=|" %%g in (%TempDir%\%LIST%) do (
call cscript.exe //nologo "%JSLOC%\SAVEASPDF.js" "%%g"
)
REM or;
REM FORFILES %%g /p %tempdir% /m *.doc /c "cscript.exe //nologo "%JSLOC%\SAVEASPDF.js" "%%g""
GOTO:EOF

:RENAMEFUNCTION
REM if you want more enumerations, change the number "50" below to whatever you want
FOR /L %%N IN (1, 1, 50) DO (
IF NOT EXIST "%TargetDir%\%~n1-R%%N%~x1" (
MOVE %1 "%TempDir%\%~n1-R%%N%~x1"
if exist "%TempDir%\%~n1-R%%N%~x1" (
    call cscript.exe //nologo "%JSLOC%\SAVEASPDF.js" "%TempDir%\%~n1-R%%N%~x1"
) else (
    GOTO:EOF
)
)
)
GOTO:EOF

REM finishing...
:FINISHING
MOVE "%TempDir%\*.*" "%TargetDir%"

REM cleaning
rmdir /S /Q "temp%dt%"

REM ===== HERE IS THE JS I USE ========

REM var fso = new ActiveXObject("Scripting.FileSystemObject");
REM var docPath = WScript.Arguments(0);
REM docPath = fso.GetAbsolutePathName(docPath);

REM var pdfPath = docPath.replace(/\.doc[^.]*$/, ".pdf");
REM var objWord = null;

REM try
REM {
    REM WScript.Echo("Saving '" + docPath + "' as '" + pdfPath + "'...");

    REM objWord = new ActiveXObject("Word.Application");
    REM objWord.Visible = false;

    REM var objDoc = objWord.Documents.Open(docPath);

    REM var wdFormatPdf = 17;
    REM objDoc.SaveAs(pdfPath, wdFormatPdf);
    REM objDoc.Close();

    REM WScript.Echo("Done.");
REM }
REM finally
REM {
    REM if (objWord != null)
    REM {
        REM objWord.Quit();
    REM }
REM }

谢谢

我想你应该完成以下几点:

forfiles /P "%tempdir%" /M "*.doc" /C "cscript.exe //nologo \"%JSLOC%\\SAVEASPDF.js\" @path"
或:

您试图使用变量
%%g
,但没有类似于标准
for
循环命令的变量;要访问枚举项,
forfiles
具有由
@
符号指示的变量,如
@path
,它返回项的完整路径;请注意,
@path
还包括周围的引号


然后,您需要在
/C
开关后转义命令行中使用的任何引号,如
\”
;或者,将每个
替换为
0x22
,这构成了它的十六进制字符代码
forfiles
将在执行之前用
替换它。实际上,我建议使用hex.code变量,因为引号是
cmd
实例的特殊字符,
forfiles
命令行正在运行,但是
cmd
不关心
forfiles
特定的
\”
转义;因此,在某些情况下,您可能会收到意外的(语法)错误。要使用文字
\
,您应该编写
\

这是工作脚本。感谢下面所有的支持

@echo on
REM WHAT IS THIS FOR?
REM i create word files on a remote shared folder. i need to move them to a 
REM local folder. Also i need to make PDF of them. if the files exist, 
REM i need to rename them like xx-R1, xx-R2 etc. up to R50 only. 
REM So this script first makes a temp folder and moves the word 
REM files there and renames them. In that temporary folder it makes 
REM pdf of the word files and then moves to the targeted folder. 
REM then must delete the temp folder. IT WORKS. I ve tried to make 
REM everything as a variable for people to benefit from it. Also you need to 
REM have the the JavaScript code called SAVEASPD.js. below i added the code 
REM i use for your reference. It works fine now. 

REM here i want to give a unique name to the temp folder
FOR /F "tokens=1-8 delims=:./" %%G IN ("%date%_%time%") DO (
SET dt=%%G%%H%%I_%%J_%%K
)
echo %dt%

REM create and set temp folder
mkdir "%SourceDir%\temp%dt%"
SET "TempDir=%SourceDir%\temp%dt%"

REM setting source folder:
SET "SourceDir=D:\TEST"

REM setting target folder
SET "TargetDir=D:\TEST\1"

REM listing criteria
SET "LIST=*.doc"

REM SAVEASPDF.js location
SET "JSLOC=D:\TEST"

REM ready to go...

FOR /F "usebackq delims=;" %%I IN (`DIR %SourceDir%\%LIST% /b`) DO (
    IF NOT EXIST "%TargetDir%\%%~nxI" (
        CALL :MOVEFILEFUNCTION "%%I"
    ) ELSE (
        CALL :RENAMEFUNCTION "%%I"
    )
)
GOTO:FINISHING
GOTO:EOF

:MOVEFILEFUNCTION
move %1 "%TempDir%"
for %%g in ("%TempDir%\%LIST%") do (cscript.exe //nologo "%JSLOC%\SAVEASPDF.js" "%%~fg")
GOTO:EOF

:RENAMEFUNCTION
REM if you want more enumerations, change the number "50" below to whatever you want
FOR /L %%N IN (1, 1, 50) DO (
IF NOT EXIST "%TargetDir%\%~n1-R%%N%~x1" (
MOVE %1 "%TempDir%\%~n1-R%%N%~x1"
REM it will not loop until it reaches 50, if the file not exists, will end the script. 
if exist "%TempDir%\%~n1-R%%N%~x1" (
    call cscript.exe //nologo "%JSLOC%\SAVEASPDF.js" "%TempDir%\%~n1-R%%N%~x1"
) else (
    GOTO:EOF
)
)
)
GOTO:EOF

REM finishing...
:FINISHING
MOVE "%TempDir%\*.*" "%TargetDir%"

REM cleaning
rmdir /S /Q "temp%dt%"

REM ========HERE IS THE JAVASCRIPT I USE=====
REM var fso = new ActiveXObject("Scripting.FileSystemObject");
REM var docPath = WScript.Arguments(0);
REM docPath = fso.GetAbsolutePathName(docPath);

REM var pdfPath = docPath.replace(/\.doc[^.]*$/, ".pdf");
REM var objWord = null;

REM try
REM {
    REM WScript.Echo("Saving '" + docPath + "' as '" + pdfPath + "'...");

    REM objWord = new ActiveXObject("Word.Application");
    REM objWord.Visible = false;

    REM var objDoc = objWord.Documents.Open(docPath);

    REM var wdFormatPdf = 17;
    REM objDoc.SaveAs(pdfPath, wdFormatPdf);
    REM objDoc.Close();

    REM WScript.Echo("Done.");
REM }
REM finally
REM {
    REM if (objWord != null)
    REM {
        REM objWord.Quit();
    REM }
REM }

FORFILES命令不像FOR命令那样使用令牌变量。我也看不出有什么理由在代码中使用FORFILES命令。FOR命令会很好,速度会快得多。通过键入命令名,后跟/?,可以查看任何命令的语法和帮助?查看命令的帮助。由于问题的范围在编辑时发生了更改,我建议您删除此问题,因为我认为它对其他人没有帮助,因为它相当混乱…感谢@squashman和您的回答。我编辑了原文。请看一看。顺便说一句,文件夹路径和文件名中都有空格。您是否已经尝试过我的
for files
命令行?你应该准确地描述你想要做什么,而不是仅仅添加更多的代码,这样会更容易帮助你…我试过了,但它将文件名打印为“*.doc”,但JS不接受这样的参数。它需要将命令写在下面;'cscript.exe//nologo\SAVEASPDF.js ANYDOC.doc'forfiles命令行在更新的代码中被注释掉了,所以问题出在其他地方!我很确定这是
:MOVEFILEFUNCTION
块;我认为您应该为%%g in(“%TempDir%\%LIST%”)编写
,而不是为/f“usebackq delims=|“%%g in(%TempDir%\%LIST%)编写
,并在循环体中编写
“%%fg”
而不是
“%%g”
f
可能会被省略,具体取决于您的
*.js脚本)…对不起,这对我来说也有点复杂。问题出在:MOVEFILEFUNCTION块中。我试了以下方法;对于%%g“usebackq delims=|“%%g in(%TempDir%\%LIST%)do(调用cscript.exe//nologo”%JSLOC%\SAVEASPDF.js”“%%~fg“再次清除,目标命令行结果如下;cscript.exe//nologo”D:\test\SAVEASPDF.js”“ANYDOC.doc”并在循环中继续;cscript.exe//nologo“D:\test\SAVEASPDF.js”“ANYotherDOC.doc”JS不接受通配符。这就是我尝试使用for循环的原因,谢谢。
@echo on
REM WHAT IS THIS FOR?
REM i create word files on a remote shared folder. i need to move them to a 
REM local folder. Also i need to make PDF of them. if the files exist, 
REM i need to rename them like xx-R1, xx-R2 etc. up to R50 only. 
REM So this script first makes a temp folder and moves the word 
REM files there and renames them. In that temporary folder it makes 
REM pdf of the word files and then moves to the targeted folder. 
REM then must delete the temp folder. IT WORKS. I ve tried to make 
REM everything as a variable for people to benefit from it. Also you need to 
REM have the the JavaScript code called SAVEASPD.js. below i added the code 
REM i use for your reference. It works fine now. 

REM here i want to give a unique name to the temp folder
FOR /F "tokens=1-8 delims=:./" %%G IN ("%date%_%time%") DO (
SET dt=%%G%%H%%I_%%J_%%K
)
echo %dt%

REM create and set temp folder
mkdir "%SourceDir%\temp%dt%"
SET "TempDir=%SourceDir%\temp%dt%"

REM setting source folder:
SET "SourceDir=D:\TEST"

REM setting target folder
SET "TargetDir=D:\TEST\1"

REM listing criteria
SET "LIST=*.doc"

REM SAVEASPDF.js location
SET "JSLOC=D:\TEST"

REM ready to go...

FOR /F "usebackq delims=;" %%I IN (`DIR %SourceDir%\%LIST% /b`) DO (
    IF NOT EXIST "%TargetDir%\%%~nxI" (
        CALL :MOVEFILEFUNCTION "%%I"
    ) ELSE (
        CALL :RENAMEFUNCTION "%%I"
    )
)
GOTO:FINISHING
GOTO:EOF

:MOVEFILEFUNCTION
move %1 "%TempDir%"
for %%g in ("%TempDir%\%LIST%") do (cscript.exe //nologo "%JSLOC%\SAVEASPDF.js" "%%~fg")
GOTO:EOF

:RENAMEFUNCTION
REM if you want more enumerations, change the number "50" below to whatever you want
FOR /L %%N IN (1, 1, 50) DO (
IF NOT EXIST "%TargetDir%\%~n1-R%%N%~x1" (
MOVE %1 "%TempDir%\%~n1-R%%N%~x1"
REM it will not loop until it reaches 50, if the file not exists, will end the script. 
if exist "%TempDir%\%~n1-R%%N%~x1" (
    call cscript.exe //nologo "%JSLOC%\SAVEASPDF.js" "%TempDir%\%~n1-R%%N%~x1"
) else (
    GOTO:EOF
)
)
)
GOTO:EOF

REM finishing...
:FINISHING
MOVE "%TempDir%\*.*" "%TargetDir%"

REM cleaning
rmdir /S /Q "temp%dt%"

REM ========HERE IS THE JAVASCRIPT I USE=====
REM var fso = new ActiveXObject("Scripting.FileSystemObject");
REM var docPath = WScript.Arguments(0);
REM docPath = fso.GetAbsolutePathName(docPath);

REM var pdfPath = docPath.replace(/\.doc[^.]*$/, ".pdf");
REM var objWord = null;

REM try
REM {
    REM WScript.Echo("Saving '" + docPath + "' as '" + pdfPath + "'...");

    REM objWord = new ActiveXObject("Word.Application");
    REM objWord.Visible = false;

    REM var objDoc = objWord.Documents.Open(docPath);

    REM var wdFormatPdf = 17;
    REM objDoc.SaveAs(pdfPath, wdFormatPdf);
    REM objDoc.Close();

    REM WScript.Echo("Done.");
REM }
REM finally
REM {
    REM if (objWord != null)
    REM {
        REM objWord.Quit();
    REM }
REM }