【问题标题】:DOS CMD batch: Wrong full pathnames? (parameter extension ~f)DOS CMD 批处理:错误的完整路径名? (参数扩展~f)
【发布时间】:2015-10-22 10:18:24
【问题描述】:

列出我可能使用的指定路径中的文件的完整路径名

FOR /F "tokens=*" %G IN ('DIR /B "path\*.*"') DO echo %~fG

错误结果:<current_directory>\*.*

ss64.com 说:“如果将没有驱动器号/路径的文件名扩展为显示驱动器号/路径,命令 shell 将假定;通常是错误的;文件驻留在当前目录中。”

这是一种非常愚蠢的行为。然而,这可能是问题所在,因为 DIR 在这里返回一个裸文件名。

有什么办法可以避免这种错误吗? 因为它很容易制作。

我知道我可以在 DIR 命令中使用 /S 选项,这会使结果成为完整路径名,但它也会通过不想要的子文件夹。

使用以下语法一切正常,但我不能使用 DIR 命令的优点:

FOR %G IN ("path\*.*") DO echo %~fG

结果:<path>\*.*

您对如何使用 DIR 和完整路径有任何提示或技巧吗?

【问题讨论】:

  • 另一个相关问题:为什么参数扩展程序~f不产生“找不到文件”的错误?
  • 如果你使用DIR /B /S会怎样?
  • 我想DIR /S 也会递归地遍历子目录,这是不需要的。

标签: batch-file cmd path pathname


【解决方案1】:

环境变量CD在任何时候都包含当前目录的路径,末尾总是没有反斜杠。

所以你可以使用你的例子:

@echo off
set "DirectoryPath=%CD%\path"
for /F "tokens=*" %%G in ('dir /B "path\*.*"') do echo %DirectoryPath%\%%G

因此,每当使用 DIR 和裸输出格式而不使用 /S 时,必须首先确定目录路径并在 FOR 循环体中引用此路径.

使用固定绝对路径的示例:

@echo off
for /F "tokens=*" %%G in ('dir /B "C:\Temp\My Folder\*.*"') do echo C:\Temp\My Folder\%%G

除了 echo 以外,别忘了在路径或文件名中包含空格的双引号!

【讨论】:

  • 谢谢,我相信这种特殊的方法只解决了 path 相对于当前目录的问题,但是,我知道有必要将路径存储在循环之外,然后将它与文件名结合起来。
  • 嗯,没错。如果在命令 DIR 上使用绝对路径,则在命令 DIR 上不使用 /S 时,FOR 循环内的文件引用也必须使用相同的路径 使用具有完整路径的文件名。
【解决方案2】:

使用FORFILES怎么样?这将为您提供任何所需文件夹的完整路径:

forfiles /p C:\Some\Directory\ /c "cmd /c echo @path"

FORFILES 非常强大,因为它提供了许多选项,例如过滤器、子文件夹搜索等。有关更多信息,请查看this 网站。

【讨论】:

  • ss64.com 是一个很棒的网站,我主要看这里。但是,我在 XP 下运行,FORFILES 在这里声明只能在带有 ResourceKit 的 XP 下使用,恐怕我没有。但我可以试一试。无论如何,谢谢。
【解决方案3】:

如果你真的需要使用dir命令

@echo off
setlocal ENABLEDELAYEDEXPANSION

set _subdir=path
set _mask=*.*

call :get_absolute_path _prefix "%CD%\%_subdir%"

rem  Iterate through a list of files, including files in subdirectories
for /f "tokens=*" %%A in ('dir /b /s /a:-d "%_prefix%\%_mask%"') do (
    rem  The current full file path
    set _f=%%A
    rem  Cut the "%CD%\%_subdir%\" prefix from the current file path
    set _f=!_f:%_prefix%\=!
    rem  Test whether the relative file path has a "subdir\" prefix:
    rem    split the relative file path by "\" delimiter and
    rem    pass %%B and %%C tokens (subdir and the remainder) to the loop
    for /f "delims=\ tokens=1*" %%B in ("!_f!") do (
        rem  If the remainder is empty string then print the full file path
        if "%%C"=="" echo %%A
    )
)

endlocal
exit /b 0

:get_absolute_path
set %1=%~f2
exit /b 0

【讨论】:

  • 谢谢。无论如何,DIR 还有其他选择吗?我想要一个按例如排序的文件列表。日期,所以我认为DIR 是一个简单的方法。
  • 不,没有这样的选项。您可以使用dir ... | findstr /r "...",但 findstr 中的正则表达式很蹩脚。而且在全文件路径中检测subdir也不容易。
  • 抱歉,我的意思是:'除了DIR,还有其他选择吗? (选项作为可能性,而不是命令选项)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
相关资源
最近更新 更多