调用具有特殊符号的文件失败
CALL on files with special symbols fail
我试图对文件夹中的每个文件进行一些操作。
for %%d in (*.txt) do call:test "%%d"
pause
exit /B
:test
echo %1
通常这很好用,但如果文件夹中有文件 %~aaa.txt
,它会说 The following usage of the path operator in batch-parameter substitution is invalid: %~aaa.txt
.
如何让它正确处理这个问题?也许有些逃避?
问题是 call
命令第二次解析命令行 call:test "%%d"
(应该读作 call :test "%%~d"
):
- 首先,
%%d
扩展到当前迭代的文件,在失败的情况下是%~aaa.txt
。
- 由于
call
命令,表达式 %~aaa.txt
现在被再次解析,其中 %~
是 argument reference 的开头,接下来的 a
是一个修饰符(~a
将扩展为文件属性),但缺少小数位(例如,%~a1
或 %~aaa2
是有效的)。
要解决这个问题,您可以将参数放入普通环境变量中并在子例程中读取它(我在其中使用 delayed variable expansion 以避免特殊字符的麻烦):
for %%d in (*.txt) do (
set "ARG=%%~d"
call :test
)
exit /B
:test
setlocal EnableDelayedExpansion
echo(!ARG!
endlocal
exit /B
您也可以将变量名作为参数传递给子例程:
for %%d in (*.txt) do (
set "ARG=%%~d"
call :test ARG
)
exit /B
:test
setlocal EnableDelayedExpansion
echo(!%~1!
endlocal
exit /B
另一种方法是让 call
在其第二个解析阶段扩展实际文件名:
for %%d in (*.txt) do (
set "ARG=%%~d"
call :test "%%ARG%%"
)
exit /B
:test
set "STR=%~1"
setlocal EnableDelayedExpansion
echo(!STR!
endlocal
exit /B
为避免文件名包含 ^
、&
或其他特殊字符的问题,避免在子例程中使用简单的 echo(%~1
。
我试图对文件夹中的每个文件进行一些操作。
for %%d in (*.txt) do call:test "%%d"
pause
exit /B
:test
echo %1
通常这很好用,但如果文件夹中有文件 %~aaa.txt
,它会说 The following usage of the path operator in batch-parameter substitution is invalid: %~aaa.txt
.
如何让它正确处理这个问题?也许有些逃避?
问题是 call
命令第二次解析命令行 call:test "%%d"
(应该读作 call :test "%%~d"
):
- 首先,
%%d
扩展到当前迭代的文件,在失败的情况下是%~aaa.txt
。 - 由于
call
命令,表达式%~aaa.txt
现在被再次解析,其中%~
是 argument reference 的开头,接下来的a
是一个修饰符(~a
将扩展为文件属性),但缺少小数位(例如,%~a1
或%~aaa2
是有效的)。
要解决这个问题,您可以将参数放入普通环境变量中并在子例程中读取它(我在其中使用 delayed variable expansion 以避免特殊字符的麻烦):
for %%d in (*.txt) do (
set "ARG=%%~d"
call :test
)
exit /B
:test
setlocal EnableDelayedExpansion
echo(!ARG!
endlocal
exit /B
您也可以将变量名作为参数传递给子例程:
for %%d in (*.txt) do (
set "ARG=%%~d"
call :test ARG
)
exit /B
:test
setlocal EnableDelayedExpansion
echo(!%~1!
endlocal
exit /B
另一种方法是让 call
在其第二个解析阶段扩展实际文件名:
for %%d in (*.txt) do (
set "ARG=%%~d"
call :test "%%ARG%%"
)
exit /B
:test
set "STR=%~1"
setlocal EnableDelayedExpansion
echo(!STR!
endlocal
exit /B
为避免文件名包含 ^
、&
或其他特殊字符的问题,避免在子例程中使用简单的 echo(%~1
。