forfiles
命令建立由前导@
表示的多个变量,这些变量将与当前迭代的项有关的数据返回到循环主体。
与迭代项目的路径和名称相关的所有变量都返回""
中包含的值。这些是:@file
,@fname
,@ext
,@path
和@relpath
。
所以:如何摆脱双引号?
例如,以下代码返回给定根目录中文本文件的相对路径:
forfiles /P "C:\root" /M "*.txt" /C "cmd /C echo @relpath"
假设C:\root
包含两个文件file1.txt
和file2.txt
,输出将是:
".\file1.txt"
".\file2.txt"
但是,我想要没有周围""
的文件列表。
我正在使用Windows 7 64位。
[一种方法是将for %I
循环嵌套在forfiles
内并使用%~I
扩展-在命令提示符窗口中使用此代码:
forfiles /P "C:\root" /M "*.txt" /C "cmd /Q /C for %I in (@relpath) do echo %~I"
要在批处理文件中使用该代码,必须将%
符号加倍:
forfiles /P "C:\root" /M "*.txt" /C "cmd /Q /C for %%I in (@relpath) do echo %%~I"
返回的文件列表将是(依赖于原始问题中的示例文件:]
.\file1.txt
.\file2.txt
[另一种变化是将另一个forfiles
嵌套在初始的主体中,因为forfiles
会删除给定字符串内的(非转义的)双引号,例如/C
之后的命令行:
forfiles /P "C:\root" /M "*.txt" /C "cmd /C forfiles /P @path\.. /M @file /C \"cmd /C echo @relpath\""
或者,(有意将内部的forfiles
加倍,这可以解决一个错误-参见this post):
forfiles /P "C:\root" /M "*.txt" /C "forfiles forfiles /P @path\.. /M @file /C \"cmd /C echo @relpath\""
内部forfiles
将精确地枚举一项,这是由外部循环传递的一项。由于执行内部循环时@relpath
已经展开,因此引号将被删除,因为它们没有被转义。
所以返回的文件列表看起来像(再次从原始问题中获取示例文件:]
.\file1.txt
.\file2.txt
行之间的附加换行符由forfiles
生成。您可以避免使用重定向(关闭forfiles
输出,但仅在控制台窗口中显示echo
输出):
> nul forfiles /P "C:\root" /M "*.txt" /C "cmd /C forfiles /P @path\.. /M @file /C 0x22cmd /C > con echo @relpath0x22"
我这样删除引号:
@ECHO OFF
GOTO START
usage:
script.bat "*.txt" "c:\Documents"
script.bat "*.txt"
script.bat
If no arguments added it will crawl the current directory with wildcard mask (*)
Avoid root directory (c:\) because too many sub directories for the output console.
:START
IF "%~2"=="" (SET "_FD=%CD%") ELSE (SET "_FD=%~2")
IF "%~1"=="" (SET "_MA=*") ELSE (SET "_MA=%~1")
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "usebackq delims=" %%A in (
`forfiles /p %_FD% /s /m %_MA% /C "cmd /c ECHO @relpath"`
) DO (
SET "myfile=%%~A"
ECHO !myfile:~2!
)
ENDLOCAL
GOTO :EOF
结果:
thumbnails\A0-1.jpg
thumbnails\new folder\img.jpg
在以下解决方案中,我看到作者使用了/ Q选项,该选项未在MS forfiles页面上记录。但这有效!怎么来的?
forfiles / P“ C:\ root” / M“ * .txt” / C“ cmd / Q / C for(@relpath)中的%I做回显%〜I”]
感谢您的回复!