如何摆脱扩展的`forfiles`变量中的双引号?

asc*_*pfl 5 quotes for-loop cmd batch-file

forfiles命令建立了几个变量,由一个领先的 表示,这些变量@将有关当前迭代项的数据返回到循环体。

所有与迭代项的路径和名称相关的变量都返回包含在 中的值""。这些是:@file@fname@ext@path@relpath

那么:你怎么能摆脱封闭的双引号呢?


例如,以下代码返回给定根目录中文本文件的相对路径:

forfiles /P "C:\root" /M "*.txt" /C "cmd /C echo @relpath"
Run Code Online (Sandbox Code Playgroud)

假设C:\root包含两个文件file1.txtand file2.txt,输出将是:

".\file1.txt"
".\file2.txt"
Run Code Online (Sandbox Code Playgroud)

但是,我想要没有周围"".

我在 Windows 7 64 位上工作。

asc*_*pfl 6

一种方法是在 中嵌套一个for %I循环forfiles并使用%~I扩展——在命令提示符窗口中使用此代码:

forfiles /P "C:\root" /M "*.txt" /C "cmd /Q /C for %I in (@relpath) do echo %~I"
Run Code Online (Sandbox Code Playgroud)

要在批处理文件中使用该代码,您必须将%-signs 加倍:

forfiles /P "C:\root" /M "*.txt" /C "cmd /Q /C for %%I in (@relpath) do echo %%~I"
Run Code Online (Sandbox Code Playgroud)

返回的文件列表将是(依赖于原始问题中的示例文件):

.\file1.txt
.\file2.txt
Run Code Online (Sandbox Code Playgroud)

另一种变体是forfiles在初始的主体中嵌套另一个,因为forfiles在给定字符串中删除(非转义)双引号,如命令行之后/C

forfiles /P "C:\root" /M "*.txt" /C "cmd /C forfiles /P @path\.. /M @file /C \"cmd /C echo @relpath\""
Run Code Online (Sandbox Code Playgroud)

或者(双倍内部forfiles是有意的,这可以解决一个错误——请参阅这篇文章):

forfiles /P "C:\root" /M "*.txt" /C "forfiles forfiles /P @path\.. /M @file /C \"cmd /C echo @relpath\""
Run Code Online (Sandbox Code Playgroud)

内部forfiles将精确枚举一项,即外部循环传递的一项。由于@relpath在执行内循环时已经展开,因此引号将被删除,因为它们没有被转义。

所以返回的文件列表看起来像(再次从原始问题中获取示例文件):

.\file1.txt

.\file2.txt
Run Code Online (Sandbox Code Playgroud)

行之间的额外换行符由 生成forfiles。您可以使用重定向来避免这种情况(关闭forfiles输出,但仅echo在控制台窗口中显示输出):

> nul forfiles /P "C:\root" /M "*.txt" /C "cmd /C forfiles /P @path\.. /M @file /C 0x22cmd /C > con echo @relpath0x22"
Run Code Online (Sandbox Code Playgroud)