问题描述
假设我们有一个变量,其中包含多行包含完整文件名的文本,例如
C:\Program Files\gs\gs9.26\Resource\CMap\Adobe-Japan2-0
C:\Program Files\Inkscape\share\poppler\cMap\Adobe-Japan2\Adobe-Japan2-0
...,并且此多行文本已分配给变量var
。
在Windows / DOS 命令提示符(不是PowerShell)中,不使用任何外部工具,如何在第一行中最后一次出现字符\
之后删除所有内容,即上述示例仅获取
C:\Program Files\gs\gs9.26\Resource\CMap\
这是我使用的代码的一部分:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /f %%x in ('copy /z "%~dpf0" nul') do set "CR=%%x"
(set LF=^
%==%
)
set TAB= "
set "TAB=%TAB:"=%
net session >nul 2>&1
if !errorLevel! NEQ 0 (
echo ERROR: Use "Run as administrator" to execute this file.!LF!
pause
exit /b 1
)
<nul set/p"=Analyzing... "
set "nil= "
for /l %%i in (2,1,80) do call set "nil=%%nil%%%nil%"
set "STDOUT="
set "STDERR="
for /f "delims=" %%E in ('
2^>^&1 ^(^
for /f "delims=" %%O in ^('^
where /R "%programfiles%" "*adobe*.*"
^^^^^^^| findstr /i /n /r "japan2"^
'^) do @^(^
echo ^^^^^^^|%%O^
^)^
^) ^| findstr /n /r "^"
') do (
set "LINE=%%E"
set "LINE=!LINE:*:=!"
if "!LINE:~,1!" == "|" (
set "STDOUT=!STDOUT!!LINE:*:=!!LF!"
) else (
set "STDERR=!STDERR!!LINE!!LF!"
)
)
解决方法
原始代码创建了尾随空格,直到找到的每个路径。我修改了代码以摆脱这种情况。
路径必须是双引号,因为它们在路径中也包含空格。因此,变量!STDOUT!
具有以下格式:
"C:\Program Files\gs\gs9.26\Resource\CMap\Adobe-Japan2-0"
"C:\Program Files\Inkscape\share\poppler\cMap\Adobe-Japan2\Adobe-Japan2-0"
您提到这只是代码的一部分,因此您需要确保其他所有功能都可以正常工作。 请注意,但是您需要复制这部分代码“完全正确” ,因为我已经对其进行了部分修改,如果没有,则不会按预期工作。
最后,我必须补充。我不确定此代码的设计原因,根据当前情况,我看不到任何具体原因。
除非您提供特定的原因,否则这段代码对现在来说有点过头了。我看不出没有任何原因,如果没有换行符,变量不能为set
。
无论如何,这里是:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
for /f %%x in ('copy /z "%~dpf0" nul') do set "CR=%%x"
(set LF=^
%==%
)
set TAB= "
set "TAB=%TAB:"=%
net session >nul 2>&1
if !errorLevel! NEQ 0 (
echo ERROR: Use "Run as administrator" to execute this file.!LF!
pause
exit /b 1
)
<nul set/p"=Analyzing... "
echo(
set "nil= "
for /l %%i in (2,1,80) do call set "nil=%%nil%%%nil%"
set "STDOUT="
set "STDERR="
for /f "delims=" %%E in ('
2^>^&1 ^(^
for /f "delims=" %%O in ^('^
where /R "%programfiles%" "*adobe*.*"
^^^^^^^| findstr /i /n /r "japan2"^
'^) do @^(^
echo ^^^^^^^|%%O^
^)^
^) ^| findstr /n /r "^"
') do (
set "LINE=%%E"
set "LINE=!LINE:*:=!"
set "LINE=!LINE: =!"
if "!LINE:~,1!" == "|" (
set STDOUT=!STDOUT!"!LINE:*:=!"!LF!
) else (
set "STDERR=!STDERR!!LINE!!LF!"
)
)
for %%i in (!STDOUT!) do set "dir=%%~dpi" & goto cont:
:cont
echo !dir!
您提供的代码的主要更改在此处:
set "LINE=!LINE: =!" :: Removed the two trailing whitespaces
if "!LINE:~,1!" == "|" (
set STDOUT=!STDOUT!"!LINE:*:=!"!LF! :: Double quote the line so we can format them correctly.
这将允许正确使用列表形式的字符串。
然后,添加了我的代码。这使用驱动器和文件路径设置pth
变量。然后,我们剥离尾随的\
,以允许下一个%%~dpa
将驱动器和路径分配给所需的点。
for %%i in (!STDOUT!) do set "dir=%%~dpi" & goto cont:
:cont
echo !dir!
结果将是:
C:\Program Files\gs\gs9.26\Resource\CMap\
最后,如果您希望看到我的代码部分确实按照需要从路径中删除了这些部分,则可以在我的代码部分中进行此操作:
for %%i in (!STDOUT!) do (
echo %%~dpi
)
或者如果您想将它们中的每一个都设置为dir[n]
以类似于数组,则将其放置在我的代码段中:
set _n=1
for %%i in (!STDOUT!) do (
set "dir[!_n!]=%%~dpi"
set /a _n+=1
)
for /l %%n in (0,!_n!) do echo(!dir[%%n]!
set dir