问题描述
我需要处理一个文件的完整路径,即 C:\fold1\fold2...\foldN\filename.dat 以便分别获取父文件夹和文件名,即 root=C:\ fold1\fold2...\foldN 和 file=filaname.dat。
这是因为无论您从何处调用主 .bat(这个),我都想概括对程序的调用,以便能够在调用此特定程序之前对 %root% 执行 pushd
.
我正在做这方面的工作,但是在摆姿势 line=%%c
时我得到了堆栈:
: before remove quotes from %var%
set var=%var:"=%
if exist %temp% (
if exist %temp%\filepath.txt del %temp%\filepath.txt
echo %var% > %temp%\filepath.txt
)
for /f "tokens=1,* delims= " %%z in (%temp%\filepath.txt) do (
set line=%%z
echo Line writes %line%.
set root=empty
goto :processtoken
)
:processtoken
for /f "tokens=1,* delims=\" %%b in ("%line%") do (
echo %%b
echo %%c
set line=%%c rem this does not work,why??
echo Now line writes %line%
if "%root%"=="empty" (
echo [INFO] Root is empty,initialising..
echo %%c
set root=%%c
) else (
set root=%root%\%%c
)
echo Root is %root%
goto :end
)
我面临的问题是,当我打印以查看 %line% 的变化情况时,它显示 %line%(在 set line=%%c
之后对应于 FULL PATH(而我的意图是递归地到达文件名,我仍然需要添加在 %%c 中查找 "\"
字符串的条件,当不再存在时,这意味着我们到了最后一步,即 %root% 现在将对应于最终的根文件夹).
感谢谁愿意帮助我解决这个问题。
编辑: 这个主程序的调用如下:
程序 arg1 arg2 arg3 arg4 arg5
arg5 是文件的路径,它将在内部作为其他程序的参数。为了尽可能通用,无论您从何处调用它,我都希望使该程序具有功能性。您仍然有两个选择:
-
您已经在包含此内部调用程序要处理的文件的文件夹中,在这种情况下,arg5 将作为 filename.dat 传递(不带引号,除非它包含空格)
-
您不在根文件夹中,因此您直接传递完整路径(如果包含空格,则使用双引号)。
问题出现在第 2 种情况下,因为当您从根目录调用该内部程序并且仅传递给它 FILENAME.DAT 时,该内部程序可以正常工作。
这就是我提出这个问题的原因。 %var% 只是 arg5,按照我在此解释的方式。
我希望我比以前更清楚了。
附注。我在各方面都不是经验丰富的程序员,所以如果我错过了许可和专业性,我深表歉意。写入/读取 %temp% 文件夹只是为了利用一种更新的批处理编程方式,没有别的。我知道这是多余的。
解决方法
因为您在评论中提到了 set var=%5
:
set "root=%~dp5"
set "file=%~nx5"
应该就是你所需要的。有关详细信息,请参阅 call /?
。
您应该看看 for 变量修饰符 (FOR /?
)
root=%%~dpz
用于扩展为:d=drive and p=path of zfile=%%~nxz
用于扩展为:n=name 和 x=z 的扩展名
然后你可以改变你的区块
for /f "tokens=1,* delims= " %%z in (%temp%\filepath.txt) do (
set "line=%%z"
set "root=%%~dpz"
set "file=%%~nxz"
REM ** Show the variables
set root
set file
)
,
在批处理文件中执行此操作的另一种方法是使用专为执行此操作而设计的 PowerShell Split-Path
命令。
SET "THEFILE=%TEMP%\file path.txt"
FOR /F "delims=" %%A IN ('powershell -NoLogo -NoProfile -Command
"""$([Convert]::ToChar(34))$(Split-Path -Path """%THEFILE%""")$([Convert]::ToChar(34)) $([Convert]::ToChar(34))$(Split-Path -Path """%THEFILE%""" -Leaf)$([Convert]::ToChar(34))"""') DO (
SET "FILESTRING=%%A"
)
SET "PATHPART="
FOR %%A IN (%FILESTRING%) DO (
IF NOT DEFINED PATHPART (SET "PATHPART=%%~A") ELSE (SET "FILEPART=%%~A")
)
ECHO PATHPART is "%PATHPART%"
ECHO FILEPART is "%FILEPART%"
当然,如果脚本是为 PowerShell 编写的,那就更容易了。
$TheFile = "$Env:TEMP\filepath.txt"
$PathPart = Split-Path -Path $TheFile
$FilePart = Split-Path -Path $TheFile -Leaf
更新:
实际上,使用PUSHD似乎不需要拆分路径。只需在末尾添加 \..
。
PUSHD C:\Users\joe\afile.txt\..