我有以下代码,但我看到for循环中的变量未正确设置。我尝试使用!
标记仍然无效。
set dev_root=.\
set prod_root=..\prod\
setlocal disableDelayedExpansion
for /f "tokens=1* delims=\" %%A in ('forfiles /s /m *.txt /c "cmd /c echo @relpath"') do for %%F in (^"%%B) do (
set "file=%%~F"
set dev_filepath="%dev_root%%file%"
set prod_filepath="%prod_root%%file%"
if exist %prod_filepath% (
fc /b %dev_filepath% %prod_filepath% > nul
if errorlevel 1 (
sd edit %prod_filepath%
echo f | xcopy /f /y %dev_filepath% %prod_filepath%
)
) else (
echo f | xcopy /f /y %dev_filepath% %prod_filepath%
sd add %prod_filepath%
)
)
endlocal
答案 0 :(得分:0)
尝试这样(虽然我不知道sd
是什么):
set dev_root=.\
set prod_root=..\prod\
setlocal enableDelayedExpansion
for /f "tokens=1* delims=\" %%A in ('forfiles /s /m *.txt /c "cmd /c echo @relpath"') do for %%F in (^"%%B) do (
set "file=%%~F"
set "dev_filepath=%dev_root%%%~F"
set "prod_filepath=%prod_root%%%~F"
if exist "!prod_filepath!" (
fc /b "!dev_filepath!" "!prod_filepath!" > nul 2>nul || (
sd edit "!prod_filepath!"
copy /Y "!dev_filepath!" "!prod_filepath!"
)
) else (
copy /Y "!dev_filepath!" "!prod_filepath!"
sd add "!prod_filepath!"
)
)
答案 1 :(得分:0)
我会改变一些事情。主要的是用forfiles
替换xcopy /L
来检索相对路径,因为后者要快得多。以下是包含大量解释性rem
备注的返工代码:
@echo off
setlocal DisableDelayedExpansion
rem /* Use the quoted `set` syntax (the `""` do not become part of the value);
rem do not include the trailing `\` here, do that later when building paths: */
set "dev_root=."
set "prod_root=..\prod"
rem /* You should change to a dedicated working directory, because you are only
rem using relative paths later: */
cd /D "%~dp0." & rem // (this is the script's parent directory, just as an example)
rem /* Use `xcopy /L` rather than `forfiles` to retrieve list of relative paths;
rem `/L` avoids to copy anything; the output is preceded by the drive letter
rem (e. g., `C:`), which is split off by the `for /F` options; the summary text
rem `?? File(s)` is not enumerated by `for /F` as it does not contain a `:`;
rem the returned items are not preceded by `.\` and are not in between `""`: */
for /F "tokens=2 delims=:" %%F in ('xcopy /L /S /I "*.txt" "%TEMP%"') do (
rem /* Build source and target paths; there is no interim variable `file`
rem necessary, use `%%F` immediately; include path separators `\` here;
rem at this point, delayed expansion is still disabled: */
set "dev_filepath=%dev_root%\%%F"
set "prod_filepath=%prod_root%\%%F"
rem /* Now let us enable delayed expansion at this point in order to be able
rem to read the previously built file paths; avoid immediate `%` expansion
rem and `for` variables beyond this point in order not to lose `!`: */
setlocal EnableDelayedExpansion
rem /* Always use quoted file paths in order to avoid trouble with white-spaces
rem and other special characters (`^`, `&`, `(`, `)`,...): */
if exist "!prod_filepath!" (
rem /* You can use the `||` operator to execute commands only if the
rem previous one failed, hence its exit is not zero: */
fc /B "!dev_filepath!" "!prod_filepath!" > nul || (
rem // I do not know the `sd` command, so I keep it, with quoted path:
sd edit "!prod_filepath!"
rem /* For copying a single file, you should use `copy` rather than
rem `xcopy`, because the former does not prompt for file/directory
rem (`F`/`D`); keep in mind the prompt is language-dependent;
rem before copying, create the destination directory: */
md "!prod_filepath!\.." 2> nul
copy /Y "!dev_filepath!" "!prod_filepath!"
)
) else (
rem /* Again use `copy` rather than `xcopy` to copy a single file: */
md "!prod_filepath!\.." 2> nul
copy /Y "!dev_filepath!" "!prod_filepath!"
rem // I do not know the `sd` command, so I keep it, but with quoted path:
sd add "!prod_filepath!"
)
rem /* End environment localisation at the end of the loop iteration in order
rem to have delayed expansion disabled at the beginning of the next loop
rem iteration and to avoid execeeding the nesting limit of `setlocal`: */
endlocal
endlocal
exit /B