Batch file 如何使FOR/F令牌更通用(路径相关)

Batch file 如何使FOR/F令牌更通用(路径相关),batch-file,cmd,token,Batch File,Cmd,Token,我的情况如下: FOR /F "tokens=2*" %I in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Startup ') DO echo "%J" 我已在HKEY\U CURRENT\U USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders下提取了一个注册表值,

我的情况如下:

FOR /F "tokens=2*" %I in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Startup ') DO echo "%J"
我已在
HKEY\U CURRENT\U USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
下提取了一个注册表值,其中包含文件夹位置

问题是,该代码适用于其中有空格的路径,但如果我对其中没有空格的路径使用相同的代码,则输出是错误的

我知道它与
代币相关,但我希望有一种方法可以让代码在这两种情况下都起作用

我目前拥有的代码如下所示:

FOR /F "tokens=2*" %I in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Startup ') DO echo "%J"
以及输出:

"%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"
附带说明:扩展
%USERPROFILE%
对我来说没有问题,我只需使用
调用
函数即可

现在,当将注册表值
Startup
的路径更改为没有空格的路径时,前面提到的代码将失败

希望有人能在这两种情况下都能做到

致以最良好的祝愿


copyitright

命令用法的
要求之一是正确使用
delims
令牌
子句(必要时)。它们必须适当地适应正在处理的行的格式

这里的问题是,
reg.exe
命令的输出不包含清晰无误的分隔符。我们通常使用默认的空格/制表符分隔符来处理
reg.exe
输出,但正如您所发现的,有时必须调整通用格式以处理不同的行

Cache    REG_EXPAND_SZ    %USERPROFILE%\AppData\Local\Microsoft\Windows\INetCache
My Pictures    REG_EXPAND_SZ    %USERPROFILE%\Pictures
在第二行中,当使用空格作为分隔符时,值名称中的附加空格需要一个不同的
tokens
子句

不,没有任何通用的方法来处理
reg.exe
命令的输出。你需要知道你的要求并适应它

另一种方法是,如果您知道值名称不包含下划线,则将其用作分隔符。这将拆分
REG.*
值类型中的行,留下一个可以使用空格作为分隔符拆分的标记

@echo关闭
setlocal enableextensions disabledelayedexpansion
对于/f“skip=2令牌=1,*delims=\%%a in('
注册查询
“HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell文件夹”
/v“我的照片”
“)do for/f”标记=1,*“%%c in(“%%b”)do echo“%%d”
另一种方法是使用另一种方法检索值。您可以使用
wmic
查询注册表。类似(对不起,西班牙语地区)

可以通过检索
sValue
行并使用引号作为分隔符来处理此输出(这不是唯一的方法,只是一个示例)

@echo关闭
setlocal enableextensions disabledelayedexpansion
对于/f令牌^=2^ delims^=^“%%a in('
WMIC/命名空间:\\root\default Class StdRegProv
调用GetExpandedStringValue
hDefKey^=“&H80000001”
sSubKeyName^=“软件\Microsoft\Windows\CurrentVersion\Explorer\Shell文件夹”
sValueName^=“我的照片”
^|查找“sValue”
“)执行回显“%%~fa”
注意
wmic
示例代码使用
Shell文件夹
子键而不是
User Shell文件夹
,因为
wmic
正在将
%userprofile%
扩展到
系统
用户配置文件文件夹,我不确定这是默认/逻辑行为还是我的ma中的问题中文。当我手头有另一台机器时,我会测试它。

此解决方案不会“使/F令牌更通用”,而是将值放在
“REG\u EXPAND\u SZ”
字符串之后,IMHO,这是您想要的

@echo off
setlocal

for /F "delims=" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Startup') do set "value=%%a"
set "value=%value:*REG_EXPAND_SZ    =%"
echo "%value%"

reg.exe
使用四个连续空格将输出中的值名称、数据类型和值相互分隔(在空行和保留键的行之后):

HKEY\U当前\U用户\软件\ Microsoft\Windows\CurrentVersion\Explorer\USER外壳文件夹
启动注册表\u扩展\u SZ%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
因此,假设值本身不包含这四个空格,您可以将它们替换为值中从未出现过的字符,然后将此字符用作分隔符,例如
|

@echo关闭
rem//“skip=2”选项跳过空行和键,使其不被迭代:
对于/F“skip=2 delims=“%%R in('
注册查询^
“HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell文件夹”^
/v“启动”
""做"(
rem//在环境变量中存储感兴趣的行:
设置“行=%%R”
rem//切换延迟扩展以不丢失感叹号:
setlocal EnableDelayedExpansion
rem/*将``替换为`|`并使用后者作为分隔符;
rem标记1被取消,但包含在循环中以进行迭代,即使在
rem第三个标记,即值,为空:*/
对于/F“tokens=2,*delims=|”%%V in(“!LINE:=|!”)do(
端部
回声(%%W
)
)
如果值名称包含四个连续空格或使用的分隔符
|
,则此方法将失败


或者,您可以搜索字符串4×空格+
REG\u
,因为所有注册表数据类型都以
REG\u
开头;然后从后面的字符串中,删除所有内容,直到接下来的四个连续空格,以提取值:

@echo关闭
rem/*eol=H`选项跳过带有键(`HKEY_*`)的行,使其不被迭代;
rem“for/F”仍将跳过空行:*/
对于/F“delims=eol=H”%%R英寸
注册查询^
“HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell文件夹”^
/v“启动”
""做"(
雷姆