批处理循环未在指定的分隔符处分隔字符串

时间:2019-01-04 06:26:42

标签: batch-file for-loop token

我正在使用一个名为“简易上下文菜单”的程序,当您在文件资源管理器中单击鼠标右键时,该程序可让我创建自定义上下文菜单。我想创建自己的上下文菜单项,该菜单项允许我将文件及其育儿文件夹结构复制到另一个目录中,但不包括育儿文件夹中的所有文件。

示例:

target file path: C:\the\big\foo\bar.txt

destination path: D:\cow

我希望文件“ bar.txt”及其育儿文件夹直到“ big”被复制到目录“ cow”中,而其他文件不在“ big”或“ foo”中。最终结果应如下所示:

D:\cow\big\foo\bar.txt

“大”仅应包含“ foo”,而“ foo”应仅包含“ bar.txt”。该程序允许我将文件作为参数发送到所选文件(在本例中为批处理文件)。

我被困在':main“子程序的for循环中,它将仅打印所选文件的整个路径,而忽略定界符。循环后'countA'返回为'1',已经打印了整个路径减去驱动器号。我不明白为什么for循环会忽略定界符,而不是将路径分成单独的文件夹名称。我这样做的原因是让用户可以选择父级文件夹应该被复制。这是我第一次批量编写实际代码,因此我仍然不完全了解“ setlocal”和其他一些东西。

我尝试过更改令牌,并且可以在斜杠之间选择各个部分,但是我无法将整个字符串捕获为单独的块。我还更改了定界符,并遇到了同样的问题。

@echo off
setlocal
set _target=""
set _dest=""
if not exist %1 goto:error_no_path
set _target=%~pnx1
echo %_target%
goto :dest_selct

:dest_selct
echo select destination folder
pause
set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please choose destination folder.',0,0).self.path""

for /f "usebackq delims=" %%I in (`powershell %psCommand%`) do set "folder=%%I"

setlocal enabledelayedexpansion
echo You chose %folder%
choice /c ync /n /m "Is this correct? ([Y]es, [N]o, [C]ancel)"
if %ERRORLEVEL% EQU 3 goto:eof
if %ERRORLEVEL% EQU 2 goto:dest_selct
if %ERRORLEVEL% EQU 1 (set _dest="%folder%")&&(goto:main)

:error_no_path
ECHO No file path/name
pause
GOTO:eof

:main
echo main
set _countA=0
echo count starts at %_countA%
for /f "tokens=* delims=\" %%F in ("%_target%") do (
    echo token %_countA% is %%F
    echo count is %_countA%
    set var!_countA!=%%F
    set /a countA+=1
)
echo var1: %var1%
echo count is now %countA%
pause

最后我应该有多个变量,每个变量都是作为目标文件父母的文件夹的名称,但是计数应该是存在的许多父文件夹以及文件本身。我实际上得到的是一个变量,它仍然包含整个目标路径。

1 个答案:

答案 0 :(得分:1)

for循环没有界限,因为您有tokens=*, 将所有令牌作为一个令牌。前导定界符被去除。 只有var0有值,没有回显的var1

要按路径段分割_target,请使用:

for %%F in ("%_target:\=" "%") do echo %%~F

您遇到的另一个问题是,如果在n提示符下选择choicegoto:dest_selct将导致setlocal enabledelayedexpansion 重新执行。由于您没有使用endlocal,因此 本地环境不断循环而没有结束。有时endlocal 是隐含的,因此您可能不需要使用它,尽管在这种情况下不是这样。

尝试此修复程序:

@echo off
setlocal
set "_target="
set "_dest="
if not exist "%~1" goto:error_no_path
set "_target=%~pnx1"
echo %_target%
goto :dest_selct

:dest_selct
echo select destination folder
pause
set "psCommand="(new-object -COM 'Shell.Application')^
.BrowseForFolder(0,'Please choose destination folder.',0,0).self.path""

for /f "usebackq delims=" %%I in (`powershell %psCommand%`) do set "folder=%%I"

echo You chose %folder%
choice /c ync /n /m "Is this correct? ([Y]es, [N]o, [C]ancel)"
if %ERRORLEVEL% EQU 3 goto:eof
if %ERRORLEVEL% EQU 2 goto:dest_selct
if %ERRORLEVEL% EQU 1 (set "_dest=%folder%") && goto:main

:error_no_path
ECHO No file path\name
pause
GOTO:eof

:main
setlocal enabledelayedexpansion
echo main
set "countA=0"
echo count starts at %countA%

rem Remove leading backslash if exist.
if "%_target:~,1%" == "\" set "_target=%_target:~1%"

rem Split into path segments.
for %%F in ("%_target:\=" "%") do (
    echo token !countA! is %%~F
    echo count is !countA!
    set "var!countA!=%%~F"
    set /a countA+=1
)

echo var1: %var1%

rem Echo all variables starting with var and their values.
set var
echo count is now %countA%
endlocal
pause
  • 调整后的双引号。
  • 将变量名_countA的实例更改为countA以匹配。
  • set var显示所有以var开头的变量进行调试。
  • 现在,
  • for循环会分散在路径段上。
  • setlocal enabledelayedexpansion移出了标签循环。
  • 修复第一个参数检查(如果未定义)。

有关变量替换即set /?的信息,请参见"%_target:\=" "%",用\替换" "