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

Posted

技术标签:

【中文标题】如何摆脱扩展的“forfiles”变量中的双引号?【英文标题】:How to get rid of enclosing double-quotes in the expanded `forfiles` variables? 【发布时间】:2015-12-06 03:36:51 【问题描述】:

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

所有与被迭代项的路径和名称相关的变量都返回""所包围的值。它们是:@file@fname@ext@path@relpath

那么:如何去掉封闭的双引号?


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

forfiles /P "C:\root" /M "*.txt" /C "cmd /C echo @relpath"

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

".\file1.txt"
".\file2.txt"

但是,我想要不带 "" 的文件列表。

我正在使用 Windows 7 64 位。

【问题讨论】:

【参考方案1】:

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

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

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

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"

【讨论】:

这似乎对我不起作用。 FORFILES /P "E:\archives" /M *.* /S /D -1 /C "cmd /Q /C FOR %I IN (@path) DO ECHO %~I" 只是给了我一个“~我在这个时候出乎意料。”每一行都有错误。 您是否像我在回答的第一句话中所说的那样将%-signs 加倍了?请注意,仅当您直接在命令提示符窗口中尝试代码时才能使用单个 %-signs... 啊!完全错过了。我已经投了反对票,并且会改变我的投票,但在编辑之前不允许这样做。您能否在答案中加粗该评论,或者在其下方为批处理文件制作另一个示例,以便它脱颖而出并允许我投票? 虽然对我没用,但我想在目标调用中同时使用 \@file 和 \@path 对文件很有用,因为我可以同时获得这两个。我收到“找不到指定的文件”的相同错误,并且他们的所有示例都使用 echo @path 上嵌套一个for 循环应该可以工作:for %I in (@path) do echo "%~I" = @path, "%~nxI" = @file【参考方案2】:

我删除这样的引号:

@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

【讨论】:

这对我有用,谢谢!我编辑了我的一点。在ECHO !myfile:~2! 行上,我将我的更改为ECHO !myfile! 以获得不带引号的完整路径。 再次只使用@relpath 并且只是回显而不是调用使用它的东西..

以上是关于如何摆脱扩展的“forfiles”变量中的双引号?的主要内容,如果未能解决你的问题,请参考以下文章

如何摆脱python windows文件路径字符串中的双反斜杠? [复制]

如何在curl PUT请求的主体中使用环境变量?

如何清除json中的双引号?

从 JSON 对象/字符串或 Java 脚本变量中删除开头和结尾的双引号?

vba 如何去掉返回结果两端的双引号?

从json响应swift中删除数组中的双引号