如何安全地将文件名附加到Windows文件夹路径参数?

时间:2014-11-02 17:40:09

标签: windows batch-file cmd

假设我有一个批处理脚本,需要参数%1中的文件夹路径。我想在路径中附加一个文件名,并在命令中使用它。是否有一种简单的方法可以在所有情况下以可靠的方式执行此操作?

我不想PUSHD %1而只是忽略之后的路径。假设我的逻辑要求当前目录保持不变。

问题是%1参数可能有也可能没有终止反斜杠 - 即c:\pathc:\path\

通常我只能使用"%~1\file.ext",因为Windows会同等地对待"c:\path\file.ext""c:\path\\file.ext"

但有一个令人讨厌的案例 - c:\

以下命令会产生此错误:The filename, directory name, or volume label syntax is incorrect.

dir "c:\\file.ext"
del "c:\\file.ext"

奇怪的是,这些命令工作正常:

if exist "c:\\file.ext" echo OK
echo text>"c:\\file.ext"
copy "c:\\file.ext" "somePath"
xcopy "c:\\file.ext" "somePath"

还有另一个有问题的情况 - c:,这意味着当我附加一个反斜杠时,驱动器C:上的当前目录会给出错误的结果。 "c:file.ext""c:\file.ext"不同。

是否有一种简单的方法可以安全地将文件名附加到任何给定的文件夹路径参数?

我并不关心UNC路径,因为我不经常使用它们,我相信有一些命令与UNC路径不相称。

注意:这是我发布配对问题和答案的情况。这个问题多年来一直是我的一个棘手问题,我最近发现了一个我认为其他人可能感兴趣的简单解决方案。

3 个答案:

答案 0 :(得分:7)

编辑 - 答案已更改为解决MC ND的评论

解决方案很简单:-) "%~f1.\file.ext"

Windows文件名不能以.<space>结尾,因此所有Windows命令都会忽略文件/文件夹名称中的尾随.<space>

反斜杠后面的一个.表示该位置的当前目录。

假设当前工作目录为c:\test,则下表显示了如何解析各种值:

"%~1"        | "%~f1.\file.ext"       | equivalent to
-------------+------------------------+------------------------
"c:\folder\" | "c:\folder\.\file.ext" | "c:\folder\file.ext"
             |                        |
"c:\folder"  | "c:\folder.\file.ext"  | "c:\folder\file.ext"
             |                        |
"c:\"        | "c:\.\file.ext"        | "c:\file.ext"
             |                        |
"c:"         | "c:\test.\file.ext"    | "c:\test\file.ext"
             |                        |
"."          | "c:\test.\file.ext"    | "c:\test\file.ext"
             |                        |
".."         | "c:\.\file.ext"        | "c:\file.ext"
             |                        |
<no value>   | "c:\test.\file.ext"    | "c:\test\file.ext"  I hadn't thought of this case
                                                            until I saw MC ND's answer

您可以使用FOR循环轻松地将表达式缩减为规范等效形式:

for %%A in ("%~f1.\file.ext") do echo "%%~fA"

正如Harry Johnston在评论中所述,此解决方案不适用于UNC根路径(\\server\shareName)或长路径(\\?\c:\somePath)。如果您需要支持其中任何一种情况,请参阅MC ND's answerHarry Johnston answer更简单,但它不支持给出无论证的情况。

答案 1 :(得分:2)

我没有看到让它适用于所有案例的方法。您的解决方案将处理所有本地路径的情况,但要处理UNC或长路径,似乎有必要首先纠正路径,然后附加文件数据

@echo off
    setlocal enableextensions disabledelayedexpansion

    for /f "delims=" %%a in ("%~f1."
    ) do for /f "delims=" %%b in ("%%~fa\file.ext"
    ) do echo "%%~fb"

这&#34;应该&#34;处理本地,网络或长路径(for /f的原因是?),绝对和相对的,以及在命令行中没有给出路径的可能性。

答案 2 :(得分:2)

由于~f消除了多个反斜杠,我认为这与原始提案一样有效,并且似乎也能正确处理共享根和长路径:

for /F "delims=" %%i in (%~f1\file.ext) do set filename=%%~fi