forfiles语法问题 - 如何使用变量

时间:2015-12-28 13:43:31

标签: 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 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 }

谢谢!

2 个答案:

答案 0 :(得分:0)

我想你想要完成以下任务:

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

或:

forfiles /P "%tempdir%" /M "*.doc" /C "cscript.exe //nologo 0x22%JSLOC%\\SAVEASPDF.js0x22 @path"

您尝试使用变量%%g,但没有像标准for循环命令那样的变量;要访问枚举项,forfiles会显示@符号所指示的变量,例如@path,它会返回项目的完整路径;请注意,@path还包含周围的引号""

然后,您需要在/C切换后转义在命令行中使用的任何引号,例如\";或者,将每个"替换为0x22,它构成其十六进制字符代码; forfiles会在执行前将其替换为"。实际上我推荐十六进制。代码变体,因为引号是cmd实例的特殊字符,forfiles命令行正在运行,但cmd并不关心forfiles - 特定\"转义;所以在某些条件下,您可能会收到意外(语法)错误。要使用文字\,您应该写\\

答案 1 :(得分:0)

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

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