【问题标题】:Correct syntax for variable modifiers when using EnableDelayedExpansion使用 EnableDelayedExpansion 时变量修饰符的正确语法
【发布时间】:2013-10-19 19:25:24
【问题描述】:

我希望能够执行 %~p 以仅查看文件的路径。但是在循环中使用它时我无法获得正确的语法(使用 EnableDelayedExpansion)

这是我的代码:

@echo off
set "dir1=%TMP%\opt"
set "dir2=c:\opt"
set "empty="

setlocal EnableDelayedExpansion
for /f %%F in ('dir  /a:-d /s /b /r "%dir1%"') do (
  set "file_path=%%F"
  set "file_name=%%~nF"
  set "new_path=!file_path:%dir1%=%dir2%!"
  set "new_path=!new_path:!file_name!=%empty%" //This command is problematic
  echo !new_path!
)
endlocal

我有什么办法吗?

【问题讨论】:

    标签: windows variables batch-file for-loop


    【解决方案1】:

    这里是获取和替换文件路径的方法。

    @echo off
    setlocal EnableDelayedExpansion
    
    set "dir1=%TMP%\opt"
    set "dir2=c:\opt"
    
    pushd "%dir1%" && for /f %%F in ('dir /a:-d /b /r /s') do (
        set "file_path=%%~dpF"
        set "new_path=!file_path:%dir1%=%dir2%!"
        echo !new_path!
    ) & popd
    
    endlocal
    exit /b 0
    

    说明

    主要变化是对变量使用了~dp 修饰符,这导致它只获取完整的文件路径而没有文件名。

    您对 dir1 替换的使用是正确的,是您的文件名替换不好。通过使用~dp 修饰符,我们可以完全跳过文件名替换部分。

    pushd 只在for 循环开始设置工作目录之前被调用一次。

    演练:

    • 将工作目录设置为dir1
    • 遍历该目录和子目录中的所有文件。
    • 对于每个文件只获取文件路径C:\Path\opt\sub 而不是C:\path\opt\sub\file.ext
    • C:\path\opt 替换为C:\opt
    • 显示结果。
    • popd 会将工作目录恢复到 pushd 之前的状态。

    这是来自for /? 帮助文本的所有变量修饰符的列表。

    In addition, substitution of FOR variable references has been enhanced.
    You can now use the following optional syntax:
    
    %~I         - expands %I removing any surrounding quotes (")
    %~fI        - expands %I to a fully qualified path name
    %~dI        - expands %I to a drive letter only
    %~pI        - expands %I to a path only
    %~nI        - expands %I to a file name only
    %~xI        - expands %I to a file extension only
    %~sI        - expanded path contains short names only
    %~aI        - expands %I to file attributes of file
    %~tI        - expands %I to date/time of file
    %~zI        - expands %I to size of file
    %~$PATH:I   - searches the directories listed in the PATH
                   environment variable and expands %I to the
                   fully qualified name of the first one found.
                   If the environment variable name is not
                   defined or the file is not found by the
                   search, then this modifier expands to the
                   empty string
    
    The modifiers can be combined to get compound results:
    
    %~dpI       - expands %I to a drive letter and path only
    %~nxI       - expands %I to a file name and extension only
    %~fsI       - expands %I to a full path name with short names only
    %~dp$PATH:I - searches the directories listed in the PATH
                   environment variable for %I and expands to the
                   drive letter and path of the first one found.
    %~ftzaI     - expands %I to a DIR like output line
    
    In the above examples %I and PATH can be replaced by other valid
    values.  The %~ syntax is terminated by a valid FOR variable name.
    Picking upper case variable names like %I makes it more readable and
    avoids confusion with the modifiers, which are not case sensitive.
    

    【讨论】:

    • 感谢您的回答,如果您有时间,请解释一下这是如何工作的?是不是因为你在每个 for 循环之后都推了 %dir1% ,所以你可以在字符串替换中使用 %dir1% ?这只是代码的一部分,完整的代码将文件扩展为 %TMP% 然后检查这些文件是否存在于另一个目录中(具有相同的子文件夹名称),如果它没有从 %tmp% 复制到该位置。这就是为什么我需要 ~p 的子字符串才能正确使用复制命令
    • @MangO_O 为答案添加了解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    相关资源
    最近更新 更多