“批处理”问题,文件名中包含& s

时间:2016-09-09 12:58:24

标签: batch-file

不太确定如何标题我遇到的问题(尽我所能尽力),但我遇到的问题是当我尝试读取文件名然后在一个文件名中使用它们时备份脚本我写的。我最初在没有&'s的名字的文件中进行了测试(不记得我有任何内容,并且直到现在都没有意识到会有问题。)

以下是在以下示例中用于调用的代码的一部分:

:backup2
if %DEBUG%=="t" echo Begin backup part 2
for %%? in ("!FILEREADIN!") do (
SET "FILENAME=%%~n?%%~x?"
SET "BACKUPFQP=%%~f?"
SET "BACKUPLAST=%%~t?"
call :getlength FILELENGTH "!FILENAME!"

无论如何,当我在我的代码中使用文件名来获取文件名的长度(在脚本的单独部分中使用)时,我遇到了这个问题。

:getlength
SETLOCAL enabledelayedexpansion
if %DEBUG%=="t" echo %2 parsed... %%2 delayed... !%2!
SET "LENGTH=!%1!"
SET "STRING=%2"
REM need to correct the string for the "" that get added from passing in %2
REM Issue arises with this part below when working on a file name with a &
SET "STRING=!STRING:~1,-1!"
:getlengthwhile
if %DEBUG%=="t" echo Length !LENGTH!
if %DEBUG%=="t" echo String left:   !STRING!
SET /a "LENGTH+=1"
REM Issue here too when working with file names with &'s
SET "STRING=%STRING:~1%"
if %DEBUG%=="t" echo Length now !LENGTH!
if %DEBUG%=="t" echo String now left:   !STRING!
if %DEBUG%=="t" pause
if not ["%STRING%"]==[""] (
if %DEBUG%=="t" echo Continuing source length calculation
Goto :getlengthwhile
) else (
if %DEBUG%=="t" echo Length calculated)
ENDLOCAL & SET TEMPNUM=%LENGTH%
SET "%~1=%TEMPNUM%"
if %DEBUG%=="t" echo !%1!
if %DEBUG%=="t" pause
goto :eof

我知道有逃避通常没有批处理脚本的错误试图使用&的权利。作为一个命令,但是当读取一个名称中包含一个(或多个)文件的文件时,如何使其正常工作?

以下是我遇到问题的文件名示例以及运行脚本时会发生什么:

File "E:\Projects\.\Abilities&Events.docx"
Press any key to continue . . .
Begin backup part 2
"Abilities&Events.docx" parsed... %2 delayed...
'Events.docx""' is not recognized as an internal or external command, operable program or batch file.

2 个答案:

答案 0 :(得分:1)

如上所述,您应该使用更多的报价和更多的延迟扩展 顺便说一句。您的代码将长度添加到%1中的变量,也许这是预期的,否则您应该将SET "LENGTH=!%1!"更改为set LENGTH=0

:getlength

SETLOCAL Enabledelayedexpansion
SET "LENGTH=!%1!"
SET "STRING=%~2"

:getlengthwhile
if defined STRING (
    set /a LENGTH+=1
    set "string=!string:~0,-1!"
    goto :getlengthwhile
)
echo !LENGTH!
(
    ENDLOCAL
    SET "%~1=%LENGTH%"
)
goto :eof

您的代码的另一个问题是这一行

call :getlength FILELENGTH "!FILENAME!"

它失败,文件名包含^,因为它们被CALL加倍。
所以最好使用

call :getlength FILELENGTH FILENAME

...

:getlength    
SETLOCAL Enabledelayedexpansion
SET "LENGTH=!%1!"
SET "STRING=!%2!"

对于更快的strlen函数,您可以查看SO: How do you get the string length in a batch file?

答案 1 :(得分:0)

我找到了问题的答案。谢谢大家的帮助。

我的解决方案是在发现我可以从此站点替换变量的部分(我可以用它来删除部分变量)之后:http://ss64.com/nt/syntax-replace.html

我不知道可以进行替换(我知道可以获取变量的一部分(参考站点:http://ss64.com/nt/syntax-substring.html“))

我最终放弃了我的getlength功能(因为它不再需要)。结果是这样的:

:backup2
if %DEBUG%=="t" echo Begin backup part 2
for %%? in ("!FILEREADIN!") do (
SET "FILENAME=%%~n?%%~x?"
SET "BACKUPFQP=%%~f?"
SET "BACKUPLAST=%%~t?"
if %DEBUG%=="t" echo Filename before "!FILENAME!"
SET FILETESTPART=!FILEREADIN!
if %DEBUG%=="t" echo !FILETESTPART!
SET "FILETESTPART=!FILETESTPART:%SOURCE%=!" 
if %DEBUG%=="t" echo Filename after "!FILETESTPART!"
SET "FILETESTPART=!FILETESTPART:~3!"
if %DEBUG%=="t" echo Filename after "!FILETESTPART!"