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

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

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

问题

  1. set /p folderPath=请键入文件夹路径:
  2. if not exist "!folderPath!" (
  3. echo 给定的路径不存在。请输入有效的路径:
  4. goto :checkFolderPath
  5. )
  6. set /p maxLevel=请键入子文件夹的最大搜索深度,其中 !folderPath! 表示 Level 0:
  7. for /f "tokens=* delims=0123456789" %%i in ("!maxLevel!") DO (
  8. if not "%%i"=="" (
  9. echo 输入必须是一个数字。请输入有效的数字,例如 2
  10. goto :checkMaxLevel
  11. )
  12. )
  13. if not defined maxLevel set maxLevel=1
  14. set currentLevel=-1
  15. set totalFiles=0
  16. set correctFiles=0
  17. set renameFiles=0
  18. set incorrectFiles=0
  19. set changedFiles=0
  20. set folderCount=0
  21. set tempPath=!folderPath!
  22. set "tempPath=!tempPath: =_!"
  23. set "tempPath=!tempPath:\=\\!"
  24. set /a "depth=1"
  25. :loop
  26. if defined tempPath (
  27. set "tempPath=!tempPath:*\\=!"
  28. if not "!tempPath!"=="!tempPath:\\=!" (
  29. set /A "depth+=1"
  30. goto :loop
  31. )
  32. )
  33. set /a rootLevel=%depth%
  34. echo 绝对文件夹深度为 "%folderPath%" 是: %rootLevel%
  35. echo.
  36. if !maxLevel! == 0 (
  37. pushd !folderpath!
  38. FOR %%R IN (*.pdf) DO (
  39. set "filename=%%~nxR"
  40. echo %%~fR
  41. set /a totalFiles+=1
  42. if "!filename:~0,4!"=="DRW_" (
  43. set /a correctFiles+=1
  44. ) else (
  45. if "!filename:~0,3!"=="500" (
  46. set /a renameFiles+=1
  47. ) else (
  48. set /a incorrectFiles+=1
  49. )
  50. )
  51. )
  52. ) else (
  53. FOR /R "%folderPath%" %%D in (.) DO (
  54. set "depth=-1"
  55. set tempPath=%%D
  56. set "tempPath=!tempPath:.=!"
  57. set "tempPath=!tempPath: =_!"
  58. set "tempPath=!tempPath:\=\\!"
  59. set /a currentLevel=!depth!-!rootLevel!
  60. if !currentLevel! leq !maxLevel! (
  61. Pushd %%D
  62. if !currentLevel! leq !maxLevel! (
  63. FOR %%G IN (*.pdf) DO (
  64. set "filename=%%~nxG"
  65. echo %%~fG
  66. set /a totalFiles+=1
  67. if "!filename:~0,4!"=="DRW_" (
  68. set /a correctFiles+=1
  69. ) else (
  70. if "!filename:~0,3!"=="500" (
  71. set /a renameFiles+=1
  72. ) else (
  73. set /a incorrectFiles+=1
  74. )
  75. )
  76. )
  77. ) else (
  78. echo 到达文件循环的最大级别,这不应该发生
  79. )
  80. popd
  81. ) else (
  82. echo 到达最大级别
  83. )
  84. )
  85. )
  86. echo.
  87. echo 总共检查的 PDF 文件数: %totalFiles%
  88. echo 正确命名的 PDF 文件数: %correctFiles%
  89. echo 需要重命名的 PDF 文件数: %renameFiles%
  90. 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:

  1. @echo off
  2. setlocal
  3. setlocal enabledelayedexpansion
  4. echo.
  5. echo If the input folder path contains a space in its name, the program won't work
  6. echo.
  7. echo.
  8. REM User input for folderPath and check
  9. :checkFolderPath
  10. set /p folderPath="Please enter the folderpath: "
  11. if not exist "!folderPath!" (
  12. echo The given path does not exist. Please enter a valid path:
  13. goto :checkFolderPath
  14. )
  15. REM User input for maxLevel and check
  16. :checkMaxLevel
  17. echo.
  18. set /p maxLevel="Please enter the max search depth for subfolders where !folderPath! represents Level 0: "
  19. echo.
  20. for /f "tokens=* delims=0123456789" %%i in ("%maxLevel%") DO (
  21. if not "%%i"=="" (
  22. echo The input has to be a number. Please enter a valid number e.g. 2.
  23. goto :checkMaxLevel
  24. )
  25. )
  26. REM initiate counter
  27. if not defined maxLevel set maxLevel=1
  28. set currentLevel=-1
  29. set totalFiles=0
  30. set correctFiles=0
  31. set renameFiles=0
  32. set incorrectFiles=0
  33. set changedFiles=0
  34. set folderCount=0
  35. set tempPath=!folderPath!
  36. REM replace space symbol by "_" and "\" by "\\"
  37. set "tempPath=!tempPath: =_!"
  38. set "tempPath=!tempPath:\=\\!"
  39. REM count number of backslashes in the path (equals folder depth)
  40. set /a "depth=1"
  41. :loop
  42. if defined tempPath (
  43. set "tempPath=!tempPath:*\\=!"
  44. if not "!tempPath!"=="!tempPath:\\=!" (
  45. set /A "depth+=1"
  46. goto :loop
  47. )
  48. )
  49. set /a rootLevel=%depth%
  50. echo The absolute folder depth of "%folderPath%" is: %rootLevel%
  51. echo.
  52. echo.
  53. REM Skip loop through folders if given maxLevel is 0
  54. if !maxLevel! == 0 (
  55. pushd !folderpath!
  56. FOR %%R IN (*.pdf) DO (
  57. set "filename=%%~nxR"
  58. echo %%~fR
  59. set /a totalFiles+=1
  60. REM echo totalFiles=!totalFiles!
  61. REM Check if filename beginns with "DRW_"
  62. if "!filename:~0,4!"=="DRW_" (
  63. set /a correctFiles+=1
  64. ) else (
  65. REM Check if filename beginns with "500"
  66. if "!filename:~0,3!"=="500" (
  67. set /a renameFiles+=1
  68. ) else (
  69. set /a incorrectFiles+=1
  70. )
  71. )
  72. )
  73. ) else (
  74. REM Loop through subfolders up to given maxLevel
  75. FOR /R "%folderPath%" %%D in (.) DO (
  76. set "depth=-1"
  77. REM echo now in %%D
  78. REM set tempPath to variable %%D and remove the . at the end
  79. set tempPath=%%D
  80. set "tempPath=!tempPath:.=!"
  81. REM replace space symbol by "_"
  82. set "tempPath=!tempPath: =_!"
  83. REM echo temp_space_replacement=!tempPath!
  84. REM replace "\" by "\\"
  85. set "tempPath=!tempPath:\=\\!"
  86. REM echo temp_backslash_doubled=!tempPath!
  87. REM count number of backslashes in the path (equals folder depth)
  88. REM echo tempPath=!tempPath!
  89. FOR /L %%K IN (1,1,15) DO (
  90. if defined tempPath (
  91. REM echo tempPath=!tempPath!
  92. set "tempPath=!tempPath:*\\=!"
  93. REM echo D1 =%%D
  94. if not "!tempPath!"=="!tempPath:\\=!" (
  95. set /A "depth+=1"
  96. REM echo xLevel=!depth!
  97. REM echo D2 =%%D
  98. )
  99. )
  100. )
  101. set /a currentLevel=!depth!-!rootLevel!
  102. REM echo calculating relative level
  103. REM echo.
  104. REM echo.
  105. REM echo absolute level=!depth!
  106. REM echo relative level=!currentLevel!
  107. REM echo maxLevel=!maxLevel!
  108. REM echo folderpath=%folderPath%
  109. REM echo D3 =%%D
  110. REM echo.
  111. REM echo.
  112. REM loop through files in the current folder
  113. if !currentLevel! leq !maxLevel! (
  114. Pushd %%D
  115. REM Echo now in %%D
  116. REM echo proecessing files in this folder...
  117. REM echo.
  118. if !currentLevel! leq !maxLevel! (
  119. FOR %%G IN (*.pdf) DO (
  120. set "filename=%%~nxG"
  121. echo %%~fG
  122. set /a totalFiles+=1
  123. REM echo totalFiles=!totalFiles!
  124. REM Check if filename beginns with "DRW_"
  125. if "!filename:~0,4!"=="DRW_" (
  126. set /a correctFiles+=1
  127. ) else (
  128. REM Check if filename beginns with "500"
  129. if "!filename:~0,3!"=="500" (
  130. set /a renameFiles+=1
  131. ) else (
  132. set /a incorrectFiles+=1
  133. )
  134. )
  135. )
  136. REM echo.
  137. ) else (
  138. echo reached maxLevel for file loop which should not happen
  139. )
  140. ) else (
  141. REM echo reached maxLevel
  142. )
  143. popd
  144. )
  145. )
  146. REM summary of found files
  147. echo.
  148. echo Number of total checked PDF files: %totalFiles%
  149. echo Number of correct named PDF files: %correctFiles%
  150. echo Number of PDF files to be renamed: %renameFiles%
  151. echo Number of other PDF files: %incorrectFiles%
  152. 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:

  1. set tempPath=!folderPath!
  2. 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

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

  1. @echo off
  2. setlocal
  3. setlocal enabledelayedexpansion
  4. REM 用户输入文件夹路径并进行检查
  5. :checkFolderPath
  6. set /p folderPath=请输入文件夹路径:
  7. if not exist "!folderPath!" (
  8. echo 给定的路径不存在。请输入有效路径:
  9. goto :checkFolderPath
  10. )
  11. REM 从给定路径中删除引号(当将文件夹拖放到cmd中时会发生)
  12. set "folderPath=!folderPath:"=!"
  13. REM 用户输入最大搜索深度并进行检查
  14. :checkMaxLevel
  15. echo.
  16. set /p maxLevel=请输入子文件夹的最大搜索深度,其中 !folderPath! 表示级别 0:
  17. echo.
  18. for /f "tokens=* delims=0123456789" %%i in ("%maxLevel%") DO (
  19. if not "%%i"=="" (
  20. echo 输入必须为数字。请输入有效数字,例如 2。
  21. goto :checkMaxLevel
  22. )
  23. )
  24. REM 初始化计数器
  25. if not defined maxLevel set maxLevel=1
  26. set currentLevel=-1
  27. set totalFiles=0
  28. set correctFiles=0
  29. set renameFiles=0
  30. set incorrectFiles=0
  31. set "tempPath=!folderPath!"
  32. REM 将空格符替换为 "_",将 "\" 替换为 "\\"
  33. set "tempPath=!tempPath: =_!"
  34. set "tempPath=!tempPath:\=\\!"
  35. REM 计算路径中的反斜杠数(等于文件夹深度)
  36. set /a "depth=1"
  37. :loop
  38. if defined tempPath (
  39. set "tempPath=!tempPath:*\\=!"
  40. if not "!tempPath!"=="!tempPath:\\=!" (
  41. set /A "depth+=1"
  42. goto :loop
  43. )
  44. )
  45. set /a rootLevel=%depth%
  46. echo 绝对文件夹深度为 "%folderPath%" 是: %rootLevel%
  47. echo.
  48. echo.
  49. REM 如果给定的 maxLevel 0,则跳过循环遍历文件夹
  50. if !maxLevel! == 0 (
  51. pushd "!folderpath!"
  52. FOR %%R IN (*.pdf) DO (
  53. set "filename=%%~nxR"
  54. echo %%~fR
  55. set /a totalFiles+=1
  56. REM 检查文件名是否以 "DRW_" 开头
  57. if "!filename:~0,4!"=="DRW_" (
  58. set /a correctFiles+=1
  59. ) else (
  60. REM 检查文件名是否以 "500" 开头
  61. if "!filename:~0,3!"=="500" (
  62. set /a renameFiles+=1
  63. ) else (
  64. set /a incorrectFiles+=1
  65. )
  66. )
  67. )
  68. ) else (
  69. REM 循环遍历子文件夹,直到达到给定的 maxLevel
  70. FOR /R "%folderPath%" %%D IN (.) DO (
  71. set "depth=-1"
  72. REM tempPath 设置为变量 %%D,并删除末尾的 "."
  73. set "tempPath=%%D"
  74. set "tempPath=!tempPath:.=!"
  75. REM 将空格符替换为 "_"
  76. set "tempPath=!tempPath: =_!"
  77. REM "\" 替换为 "\\"
  78. set "tempPath=!tempPath:\=\\!"
  79. REM 计算路径中的反斜杠数(等于文件夹深度)
  80. FOR /L %%K IN (1,1,15) DO (
  81. if defined tempPath (
  82. set "tempPath=!tempPath:*\\=!"
  83. if not "!tempPath!"=="!tempPath:\\=!" (
  84. set /A "depth+=1"
  85. )
  86. )
  87. )
  88. REM 计算相对级别
  89. set /a currentLevel=!depth!-!rootLevel!
  90. REM 循环遍历当前文件夹中的文件
  91. if !currentLevel! leq !maxLevel! (
  92. Pushd "%%D"
  93. if !currentLevel! leq !maxLevel! (
  94. FOR %%G IN (*.pdf) DO (
  95. set "filename=%%~nxG"
  96. echo %%~fG
  97. set /a totalFiles+=1
  98. REM 检查文件名是否以 "DRW_" 开头
  99. if "!filename:~0,4!"=="DRW_" (
  100. set /a correctFiles+=1
  101. ) else (
  102. REM 检查文件名是否以 "500" 开头
  103. if "!filename:~0,3!"=="500" (
  104. set /a renameFiles+=1
  105. ) else (
  106. set /a incorrectFiles+=1
  107. )
  108. )
  109. )
  110. ) else (
  111. echo 到达了文件循环的 maxLevel,这不应该发生
  112. )
  113. popd
  114. ) else (
  115. REM 到达 maxLevel
  116. )
  117. )
  118. )
  119. REM 汇总找到的文件
  120. echo.
  121. echo 总共检查的 PDF 文件数: %totalFiles%
  122. echo 正确命名的 PDF 文件数: %correctFiles%
  123. echo 需要重命名的 PDF 文件数: %renameFiles%
  124. echo 其他 PDF 文件数: %incorrectFiles%
  125. pause

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

英文:

Now this is the code, that works as supposed:

  1. @echo off
  2. setlocal
  3. setlocal enabledelayedexpansion
  4. REM User input for folderPath and check
  5. :checkFolderPath
  6. set /p folderPath="Please enter the folderpath: "
  7. if not exist "!folderPath!" (
  8. echo The given path does not exist. Please enter a valid path:
  9. goto :checkFolderPath
  10. )
  11. REM remove quotiation marks from a given path (happens when drag and drop a folder into cmd)
  12. set "folderPath=!folderPath:"=!"
  13. REM User input for maxLevel and check
  14. :checkMaxLevel
  15. echo.
  16. set /p maxLevel="Please enter the max search depth for subfolders where !folderPath! represents Level 0: "
  17. echo.
  18. for /f "tokens=* delims=0123456789" %%i in ("%maxLevel%") DO (
  19. if not "%%i"=="" (
  20. echo The input has to be a number. Please enter a valid number e.g. 2.
  21. goto :checkMaxLevel
  22. )
  23. )
  24. REM initiate counter
  25. if not defined maxLevel set maxLevel=1
  26. set currentLevel=-1
  27. set totalFiles=0
  28. set correctFiles=0
  29. set renameFiles=0
  30. set incorrectFiles=0
  31. set changedFiles=0
  32. set "tempPath=!folderPath!"
  33. REM replace space symbol by "_" and "\" by "\\"
  34. set "tempPath=!tempPath: =_!"
  35. set "tempPath=!tempPath:\=\\!"
  36. REM count number of backslashes in the path (equals folder depth)
  37. set /a "depth=1"
  38. :loop
  39. if defined tempPath (
  40. set "tempPath=!tempPath:*\\=!"
  41. if not "!tempPath!"=="!tempPath:\\=!" (
  42. set /A "depth+=1"
  43. goto :loop
  44. )
  45. )
  46. set /a rootLevel=%depth%
  47. echo The absolute folder depth of "%folderPath%" is: %rootLevel%
  48. echo.
  49. echo.
  50. REM Skip loop through folders if given maxLevel is 0
  51. if !maxLevel! == 0 (
  52. pushd "!folderpath!"
  53. FOR %%R IN (*.pdf) DO (
  54. set "filename=%%~nxR"
  55. echo %%~fR
  56. set /a totalFiles+=1
  57. REM echo totalFiles=!totalFiles!
  58. REM Check if filename beginns with "DRW_"
  59. if "!filename:~0,4!"=="DRW_" (
  60. set /a correctFiles+=1
  61. ) else (
  62. REM Check if filename beginns with "500"
  63. if "!filename:~0,3!"=="500" (
  64. set /a renameFiles+=1
  65. ) else (
  66. set /a incorrectFiles+=1
  67. )
  68. )
  69. )
  70. ) else (
  71. REM Loop through subfolders up to given maxLevel
  72. FOR /R "%folderPath%" %%D in (.) DO (
  73. set "depth=-1"
  74. REM set tempPath to variable %%D and remove the . at the end
  75. set "tempPath=%%D"
  76. set "tempPath=!tempPath:.=!"
  77. REM replace space symbol by "_"
  78. set "tempPath=!tempPath: =_!"
  79. REM replace "\" by "\\"
  80. set "tempPath=!tempPath:\=\\!"
  81. REM count number of backslashes in the path (equals folder depth)
  82. FOR /L %%K IN (1,1,15) DO (
  83. if defined tempPath (
  84. REM echo tempPath=!tempPath!
  85. set "tempPath=!tempPath:*\\=!"
  86. REM echo D1 =%%D
  87. if not "!tempPath!"=="!tempPath:\\=!" (
  88. set /A "depth+=1"
  89. REM echo xLevel=!depth!
  90. REM echo D2 =%%D
  91. )
  92. )
  93. )
  94. REM echo calculating relative level
  95. set /a currentLevel=!depth!-!rootLevel!
  96. REM loop through files in the current folder
  97. if !currentLevel! leq !maxLevel! (
  98. Pushd "%%D"
  99. if !currentLevel! leq !maxLevel! (
  100. FOR %%G IN (*.pdf) DO (
  101. set "filename=%%~nxG"
  102. echo %%~fG
  103. set /a totalFiles+=1
  104. REM echo totalFiles=!totalFiles!
  105. REM Check if filename beginns with "DRW_"
  106. if "!filename:~0,4!"=="DRW_" (
  107. set /a correctFiles+=1
  108. ) else (
  109. REM Check if filename beginns with "500"
  110. if "!filename:~0,3!"=="500" (
  111. set /a renameFiles+=1
  112. ) else (
  113. set /a incorrectFiles+=1
  114. )
  115. )
  116. )
  117. ) else (
  118. echo reached maxLevel for file loop which should not happen
  119. )
  120. ) else (
  121. REM echo reached maxLevel
  122. )
  123. popd
  124. )
  125. )
  126. REM summary of found files
  127. echo.
  128. echo Number of total checked PDF files: %totalFiles%
  129. echo Number of correct named PDF files: %correctFiles%
  130. echo Number of PDF files to be renamed: %renameFiles%
  131. echo Number of other PDF files: %incorrectFiles%
  132. 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:

确定