我的批处理代码为什么在文件夹名称中包含空格时会出现语法错误?

huangapple go评论64阅读模式
英文:

Why does my batch code give a syntax error for a folder name with space in it?

问题

set /p folderPath=请键入文件夹路径: 
if not exist "!folderPath!" (
    echo 给定的路径不存在。请输入有效的路径:
    goto :checkFolderPath
)

set /p maxLevel=请键入子文件夹的最大搜索深度,其中 !folderPath! 表示 Level 0: 
for /f "tokens=* delims=0123456789" %%i in ("!maxLevel!") DO (
    if not "%%i"=="" (
        echo 输入必须是一个数字。请输入有效的数字,例如 2。
        goto :checkMaxLevel
    )
)

if not defined maxLevel set maxLevel=1
set currentLevel=-1
set totalFiles=0
set correctFiles=0
set renameFiles=0
set incorrectFiles=0
set changedFiles=0
set folderCount=0
set tempPath=!folderPath!

set "tempPath=!tempPath: =_!"
set "tempPath=!tempPath:\=\\!"

set /a "depth=1"

:loop
if defined tempPath (
    set "tempPath=!tempPath:*\\=!"
    if not "!tempPath!"=="!tempPath:\\=!" (
        set /A "depth+=1"
        goto :loop
    )
)

set /a rootLevel=%depth%

echo 绝对文件夹深度为 "%folderPath%" 是: %rootLevel%
echo.

if !maxLevel! == 0 (    
    pushd !folderpath!
    FOR %%R IN (*.pdf) DO (                
        set "filename=%%~nxR"
        echo %%~fR
        set /a totalFiles+=1
        if "!filename:~0,4!"=="DRW_" (
            set /a correctFiles+=1
        ) else (
            if "!filename:~0,3!"=="500" (
                set /a renameFiles+=1
            ) else (
                set /a incorrectFiles+=1
            )
        )
    )
) else (
    FOR /R "%folderPath%" %%D in (.) DO (
        set "depth=-1"
        set tempPath=%%D
        set "tempPath=!tempPath:.=!"

        set "tempPath=!tempPath: =_!"
        set "tempPath=!tempPath:\=\\!"			

        set /a currentLevel=!depth!-!rootLevel!

        if !currentLevel! leq !maxLevel! (
            Pushd %%D
            if !currentLevel! leq !maxLevel! (
                FOR %%G IN (*.pdf) DO (                
                    set "filename=%%~nxG"
                    echo %%~fG
                    set /a totalFiles+=1
                    if "!filename:~0,4!"=="DRW_" (
                        set /a correctFiles+=1
                    ) else (
                        if "!filename:~0,3!"=="500" (
                            set /a renameFiles+=1
                        ) else (
                            set /a incorrectFiles+=1
                        )
                    )
                )
            ) else (
                echo 到达文件循环的最大级别,这不应该发生
            )
            popd
        ) else (
            echo 到达最大级别
        )
    )
)

echo.
echo 总共检查的 PDF 文件数: %totalFiles%
echo 正确命名的 PDF 文件数: %correctFiles%
echo 需要重命名的 PDF 文件数: %renameFiles%
echo 其他 PDF 文件数: %incorrectFiles%
英文:

This is my first question here and I am not a programmer but an mechanical engineer doing some IT stuff for my company. So my task is to write a batch code to find all PDF files in a directory and check them for their correct names. I get this done with one exeption. The programm is given a directory by the user e.g. c:\users\guy\one space\nospace\ then the programm works as is should. The space in the folder name "one space" is no problem. However, if the given directory would be c:\users\guy\one space\ then the code aborts with something like "cannot be processed syntactically at this point" (translated from my german command promt). So this is my code, maybe someone has a clue about my mistake:

@echo off
setlocal
setlocal enabledelayedexpansion
echo.
echo If the input folder path contains a space in its name, the program won't work
echo.
echo.
REM User input for folderPath and check
:checkFolderPath
set /p folderPath="Please enter the folderpath: "
if not exist "!folderPath!" (
echo The given path does not exist. Please enter a valid path:
goto :checkFolderPath
)
REM User input for maxLevel and check
:checkMaxLevel
echo.
set /p maxLevel="Please enter the max search depth for subfolders where !folderPath! represents Level 0: "
echo.
for /f "tokens=* delims=0123456789" %%i in ("%maxLevel%") DO (
if not "%%i"=="" (
echo The input has to be a number. Please enter a valid number e.g. 2.
goto :checkMaxLevel
)
)
REM initiate counter
if not defined maxLevel set maxLevel=1
set currentLevel=-1
set totalFiles=0
set correctFiles=0
set renameFiles=0
set incorrectFiles=0
set changedFiles=0
set folderCount=0
set tempPath=!folderPath!
REM replace space symbol by "_" and "\" by "\\"
set "tempPath=!tempPath: =_!"
set "tempPath=!tempPath:\=\\!"
REM count number of backslashes in the path (equals folder depth)
set /a "depth=1"
:loop
if defined tempPath (
set "tempPath=!tempPath:*\\=!"
if not "!tempPath!"=="!tempPath:\\=!" (
set /A "depth+=1"
goto :loop
)
)
set /a rootLevel=%depth%
echo The absolute folder depth of "%folderPath%" is: %rootLevel%
echo.
echo.
REM Skip loop through folders if given maxLevel is 0
if !maxLevel! == 0 (	
pushd !folderpath!
FOR %%R IN (*.pdf) DO (                
set "filename=%%~nxR"
echo %%~fR
set /a totalFiles+=1
REM echo totalFiles=!totalFiles!
REM Check if filename beginns with "DRW_"
if "!filename:~0,4!"=="DRW_" (
set /a correctFiles+=1
) else (
REM Check if filename beginns with "500"
if "!filename:~0,3!"=="500" (
set /a renameFiles+=1
) else (
set /a incorrectFiles+=1
)
)
)
) else (
REM Loop through subfolders up to given maxLevel
FOR /R "%folderPath%" %%D in (.) DO (
set "depth=-1"
REM echo now in %%D
REM set tempPath to variable %%D and remove the . at the end
set tempPath=%%D
set "tempPath=!tempPath:.=!"
REM replace space symbol by "_"
set "tempPath=!tempPath: =_!"
REM echo temp_space_replacement=!tempPath!
REM replace "\" by "\\"
set "tempPath=!tempPath:\=\\!"			
REM echo temp_backslash_doubled=!tempPath!
REM count number of backslashes in the path (equals folder depth)
REM echo tempPath=!tempPath!
FOR /L %%K IN (1,1,15) DO (
if defined tempPath (
REM echo tempPath=!tempPath!		
set "tempPath=!tempPath:*\\=!"        	
REM echo D1 =%%D
if not "!tempPath!"=="!tempPath:\\=!" (
set /A "depth+=1"
REM echo xLevel=!depth!
REM echo D2 =%%D		       
)
)
)
set /a currentLevel=!depth!-!rootLevel!
REM echo calculating relative level
REM echo.
REM echo.
REM echo absolute level=!depth!
REM echo relative level=!currentLevel!
REM echo maxLevel=!maxLevel!
REM echo folderpath=%folderPath%
REM echo D3 =%%D
REM echo.
REM echo.
REM loop through files in the current folder
if !currentLevel! leq !maxLevel! (
Pushd %%D
REM Echo now in %%D
REM echo proecessing files in this folder...
REM echo.
if !currentLevel! leq !maxLevel! (
FOR %%G IN (*.pdf) DO (                
set "filename=%%~nxG"
echo %%~fG
set /a totalFiles+=1
REM echo totalFiles=!totalFiles!
REM Check if filename beginns with "DRW_"
if "!filename:~0,4!"=="DRW_" (
set /a correctFiles+=1
) else (
REM Check if filename beginns with "500"
if "!filename:~0,3!"=="500" (
set /a renameFiles+=1
) else (
set /a incorrectFiles+=1
)
)
)
REM echo.
) else (
echo reached maxLevel for file loop which should not happen	   
)
) else (
REM echo reached maxLevel
)
popd
)
)
REM summary of found files
echo.
echo Number of total checked PDF files: %totalFiles%
echo Number of correct named PDF files: %correctFiles%
echo Number of PDF files to be renamed: %renameFiles%
echo Number of other PDF files: %incorrectFiles%
pause

I have no other idea, but maybe someone else has one.

答案1

得分: 0

您大部分时间都使用了设置变量的方式“var=value”。但是有几行您使用了“set var=value”的方式。这可能是导致文件夹名称中含有空格的问题以及文件/文件夹名称中特殊字符(例如“&”字符)可能会出现问题的原因。
需要更改的行是:

set tempPath=!folderPath!
set tempPath=%%D

我不确定对于pushd命令是否需要,但在使用文件/文件夹名称时,请始终使用双引号。安全第一。

关于延迟扩展的使用还有一点要注意。如果您的文件/文件夹名称中包含“!”字符,这些名称可能会失败,因为启用了延迟扩展会剥离“!”字符。

英文:

You are using most of the time the set "var=value" way to set variables. But there are a few lines where you have used the set var=value way. This is likely the cause of the problems with the folder with a space and may als cause problems with special characters in file/folder names, for example the & character.
Lines to changes are:

set tempPath=!folderPath!
set tempPath=%%D

I am not sure if it is necessary for the pushd command, but when using file/foldernames always use double quot's. Better safe than sorry.

One more remark regarding the use of delayed expansion. If you have folders/files with the ! character these will fail because the enabled delayed expansion will strip the ! character.

答案2

得分: 0

以下是正常工作的代码部分的翻译:

@echo off
setlocal
setlocal enabledelayedexpansion

REM 用户输入文件夹路径并进行检查
:checkFolderPath
set /p folderPath=请输入文件夹路径: 
if not exist "!folderPath!" (
    echo 给定的路径不存在。请输入有效路径:
    goto :checkFolderPath
)

REM 从给定路径中删除引号(当将文件夹拖放到cmd中时会发生)
set "folderPath=!folderPath:"=!"

REM 用户输入最大搜索深度并进行检查
:checkMaxLevel
echo.
set /p maxLevel=请输入子文件夹的最大搜索深度,其中 !folderPath! 表示级别 0: 
echo.
for /f "tokens=* delims=0123456789" %%i in ("%maxLevel%") DO (
    if not "%%i"=="" (
        echo 输入必须为数字。请输入有效数字,例如 2。
        goto :checkMaxLevel
    )
)

REM 初始化计数器
if not defined maxLevel set maxLevel=1
set currentLevel=-1
set totalFiles=0
set correctFiles=0
set renameFiles=0
set incorrectFiles=0
set "tempPath=!folderPath!"

REM 将空格符替换为 "_",将 "\" 替换为 "\\"
set "tempPath=!tempPath: =_!"
set "tempPath=!tempPath:\=\\!"

REM 计算路径中的反斜杠数(等于文件夹深度)
set /a "depth=1"

:loop
if defined tempPath (
    set "tempPath=!tempPath:*\\=!"
    if not "!tempPath!"=="!tempPath:\\=!" (
        set /A "depth+=1"
        goto :loop
    )
)

set /a rootLevel=%depth%

echo 绝对文件夹深度为 "%folderPath%" 是: %rootLevel%
echo.
echo.

REM 如果给定的 maxLevel 为 0,则跳过循环遍历文件夹
if !maxLevel! == 0 (		
    pushd "!folderpath!"
    FOR %%R IN (*.pdf) DO (                
        set "filename=%%~nxR"
        echo %%~fR
        set /a totalFiles+=1
        REM 检查文件名是否以 "DRW_" 开头
        if "!filename:~0,4!"=="DRW_" (
            set /a correctFiles+=1
        ) else (
            REM 检查文件名是否以 "500" 开头
            if "!filename:~0,3!"=="500" (
                set /a renameFiles+=1
            ) else (
                set /a incorrectFiles+=1
            )
        )
    )
) else (
    REM 循环遍历子文件夹,直到达到给定的 maxLevel
    FOR /R "%folderPath%" %%D IN (.) DO (
        set "depth=-1"
    
        REM 将 tempPath 设置为变量 %%D,并删除末尾的 "."
        set "tempPath=%%D"
        set "tempPath=!tempPath:.=!"
    
        REM 将空格符替换为 "_"
        set "tempPath=!tempPath: =_!"
        
        REM 将 "\" 替换为 "\\"
        set "tempPath=!tempPath:\=\\!"            
        
        REM 计算路径中的反斜杠数(等于文件夹深度)
        FOR /L %%K IN (1,1,15) DO (
            if defined tempPath (
                set "tempPath=!tempPath:*\\=!"        	     
                if not "!tempPath!"=="!tempPath:\\=!" (
                    set /A "depth+=1"
                )
            )
        )
        
        REM 计算相对级别
        set /a currentLevel=!depth!-!rootLevel!
        
        REM 循环遍历当前文件夹中的文件
        if !currentLevel! leq !maxLevel! (
            Pushd "%%D"
            if !currentLevel! leq !maxLevel! (
                FOR %%G IN (*.pdf) DO (                
                    set "filename=%%~nxG"
                    echo %%~fG
                    set /a totalFiles+=1
                    REM 检查文件名是否以 "DRW_" 开头
                    if "!filename:~0,4!"=="DRW_" (
                        set /a correctFiles+=1
                    ) else (
                        REM 检查文件名是否以 "500" 开头
                        if "!filename:~0,3!"=="500" (
                            set /a renameFiles+=1
                        ) else (
                            set /a incorrectFiles+=1
                        )
                    )
                )		
            ) else (
                echo 到达了文件循环的 maxLevel,这不应该发生	   
            )
            popd
        ) else (
            REM 到达 maxLevel
        )
    )
)

REM 汇总找到的文件
echo.
echo 总共检查的 PDF 文件数: %totalFiles%
echo 正确命名的 PDF 文件数: %correctFiles%
echo 需要重命名的 PDF 文件数: %renameFiles%
echo 其他 PDF 文件数: %incorrectFiles%

pause

注意:这是代码部分的翻译,不包括代码之外的任何额外内容。

英文:

Now this is the code, that works as supposed:

@echo off
setlocal
setlocal enabledelayedexpansion
REM User input for folderPath and check
:checkFolderPath
set /p folderPath="Please enter the folderpath: "
if not exist "!folderPath!" (
echo The given path does not exist. Please enter a valid path:
goto :checkFolderPath
)
REM remove quotiation marks from a given path (happens when drag and drop a folder into cmd)
set "folderPath=!folderPath:"=!"
REM User input for maxLevel and check
:checkMaxLevel
echo.
set /p maxLevel="Please enter the max search depth for subfolders where !folderPath! represents Level 0: "
echo.
for /f "tokens=* delims=0123456789" %%i in ("%maxLevel%") DO (
if not "%%i"=="" (
echo The input has to be a number. Please enter a valid number e.g. 2.
goto :checkMaxLevel
)
)
REM initiate counter
if not defined maxLevel set maxLevel=1
set currentLevel=-1
set totalFiles=0
set correctFiles=0
set renameFiles=0
set incorrectFiles=0
set changedFiles=0
set "tempPath=!folderPath!"
REM replace space symbol by "_" and "\" by "\\"
set "tempPath=!tempPath: =_!"
set "tempPath=!tempPath:\=\\!"
REM count number of backslashes in the path (equals folder depth)
set /a "depth=1"
:loop
if defined tempPath (
set "tempPath=!tempPath:*\\=!"
if not "!tempPath!"=="!tempPath:\\=!" (
set /A "depth+=1"
goto :loop
)
)
set /a rootLevel=%depth%
echo The absolute folder depth of "%folderPath%" is: %rootLevel%
echo.
echo.
REM Skip loop through folders if given maxLevel is 0
if !maxLevel! == 0 (		
pushd "!folderpath!"
FOR %%R IN (*.pdf) DO (                
set "filename=%%~nxR"
echo %%~fR
set /a totalFiles+=1
REM echo totalFiles=!totalFiles!
REM Check if filename beginns with "DRW_"
if "!filename:~0,4!"=="DRW_" (
set /a correctFiles+=1
) else (
REM Check if filename beginns with "500"
if "!filename:~0,3!"=="500" (
set /a renameFiles+=1
) else (
set /a incorrectFiles+=1
)
)
)
) else (
REM Loop through subfolders up to given maxLevel
FOR /R "%folderPath%" %%D in (.) DO (
set "depth=-1"
REM set tempPath to variable %%D and remove the . at the end
set "tempPath=%%D"
set "tempPath=!tempPath:.=!"
REM replace space symbol by "_"
set "tempPath=!tempPath: =_!"
REM replace "\" by "\\"
set "tempPath=!tempPath:\=\\!"			
REM count number of backslashes in the path (equals folder depth)
FOR /L %%K IN (1,1,15) DO (
if defined tempPath (
REM echo tempPath=!tempPath!		
set "tempPath=!tempPath:*\\=!"        	
REM echo D1 =%%D
if not "!tempPath!"=="!tempPath:\\=!" (
set /A "depth+=1"
REM echo xLevel=!depth!
REM echo D2 =%%D		       
)
)
)
REM echo calculating relative level
set /a currentLevel=!depth!-!rootLevel!
REM loop through files in the current folder
if !currentLevel! leq !maxLevel! (
Pushd "%%D"
if !currentLevel! leq !maxLevel! (
FOR %%G IN (*.pdf) DO (                
set "filename=%%~nxG"
echo %%~fG
set /a totalFiles+=1
REM echo totalFiles=!totalFiles!
REM Check if filename beginns with "DRW_"
if "!filename:~0,4!"=="DRW_" (
set /a correctFiles+=1
) else (
REM Check if filename beginns with "500"
if "!filename:~0,3!"=="500" (
set /a renameFiles+=1
) else (
set /a incorrectFiles+=1
)
)
)		
) else (
echo reached maxLevel for file loop which should not happen	   
)
) else (
REM echo reached maxLevel
)
popd
)
)
REM summary of found files
echo.
echo Number of total checked PDF files: %totalFiles%
echo Number of correct named PDF files: %correctFiles%
echo Number of PDF files to be renamed: %renameFiles%
echo Number of other PDF files: %incorrectFiles%
pause

huangapple
  • 本文由 发表于 2023年5月26日 16:06:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76338845.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定