处理路径字符串 BATCH
Manipulate path string BATCH
我需要处理文件的完整路径,即C:\fold1\fold2...\foldN\filename.dat,以便分别获取父文件夹和文件名,即root =C:\fold1\fold2...\foldN 和文件=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
之后对应于完整路径(而我的意图是递归地获取到文件名,我仍然需要添加在 %%c 中找到 "\"
字符串的条件,当不再存在时,这意味着我们到了最后一步,即 %root% 现在将对应于最终根文件夹)。
感谢谁会尽力帮助我解决这个问题。
编辑:
这个主程序调用如下:
prog arg1 arg2 arg3 arg4 arg5
arg5 是文件的路径,该文件将在内部成为该其他程序的参数。为了尽可能通用,无论您从哪里调用它,我都想让这个程序发挥作用。你还有两个选择:
您已经位于包含此内部调用程序要处理的文件的文件夹中,在这种情况下,arg5 将作为 filename.dat 传递(不带引号,除非它包含空格)
您不在根文件夹中,因此您直接传递完整路径(如果包含空格,则用双引号引起来)。
问题出在情况 2 中,因为当您从根目录调用它并且您只传递给它时,这个内部程序可以正常工作 FILENAME.DAT。
这就是我提出这个问题的原因。 %var% 就是 arg5,按照我在此解释的方式。
我希望我比以前更清楚一点。
PS。我在各方面都不是一个经验丰富的程序员,所以如果我错过了许可和专业精神,我深表歉意。 write/read from/to %temp% 文件夹只是为了利用一种更新的批量编程方式,没有别的。我就知道是多余的
您应该看看 for 变量修饰符 (FOR /?
)
root=%%~dpz
用于展开为:d=drive and p=path of z
file=%%~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\..
因为您在评论中提到了 set var=%5
:
set "root=%~dp5"
set "file=%~nx5"
应有尽有。有关详细信息,请参阅 call /?
。
我需要处理文件的完整路径,即C:\fold1\fold2...\foldN\filename.dat,以便分别获取父文件夹和文件名,即root =C:\fold1\fold2...\foldN 和文件=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
之后对应于完整路径(而我的意图是递归地获取到文件名,我仍然需要添加在 %%c 中找到 "\"
字符串的条件,当不再存在时,这意味着我们到了最后一步,即 %root% 现在将对应于最终根文件夹)。
感谢谁会尽力帮助我解决这个问题。
编辑: 这个主程序调用如下:
prog arg1 arg2 arg3 arg4 arg5
arg5 是文件的路径,该文件将在内部成为该其他程序的参数。为了尽可能通用,无论您从哪里调用它,我都想让这个程序发挥作用。你还有两个选择:
您已经位于包含此内部调用程序要处理的文件的文件夹中,在这种情况下,arg5 将作为 filename.dat 传递(不带引号,除非它包含空格)
您不在根文件夹中,因此您直接传递完整路径(如果包含空格,则用双引号引起来)。
问题出在情况 2 中,因为当您从根目录调用它并且您只传递给它时,这个内部程序可以正常工作 FILENAME.DAT。
这就是我提出这个问题的原因。 %var% 就是 arg5,按照我在此解释的方式。
我希望我比以前更清楚一点。
PS。我在各方面都不是一个经验丰富的程序员,所以如果我错过了许可和专业精神,我深表歉意。 write/read from/to %temp% 文件夹只是为了利用一种更新的批量编程方式,没有别的。我就知道是多余的
您应该看看 for 变量修饰符 (FOR /?
)
root=%%~dpz
用于展开为:d=drive and p=path of z
file=%%~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\..
因为您在评论中提到了 set var=%5
:
set "root=%~dp5"
set "file=%~nx5"
应有尽有。有关详细信息,请参阅 call /?
。