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

假设我有一个批处理脚本,需要参数%1的文件夹path。 我想追加一个文件名到path,并在一个命令中使用。 有没有一种简单的方法可以在所有情况下都可靠?

我不想PUSHD %1并简单地忽略之后的path。 假设我的逻辑要求当前目录保持不变。

问题是%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"不一样。

有没有一种简单的方法来安全地追加文件名到任何给定的文件夹path参数?

我不关心UNCpath,因为我不经常使用它们,而且我相信有一些命令对UNCpath不好用。

注意:这是我发布配对的问题和答案的情况。 这个问题多年来一直在我身边刺痛,最近我刚刚发现了一个我认为别人可能会感兴趣的简单解决scheme。

Solutions Collecting From Web of "如何安全地将文件名附加到Windows文件夹path参数?"

编辑 – 回答改为解决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的答案 。 哈里·约翰斯顿的答案比较简单,但不支持没有任何争论的情况。

我没有办法让所有的情况都可以发挥作用。 您的解决方案将处理所有本地路径的情况下,但处理UNC或长路径似乎有必要首先纠正路径,然后附加文件数据

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

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

由于〜f消除了多个反斜杠,我认为这和原来的建议一样好,也似乎正确地处理了共享根和长路径:

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