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

scr*_*ode 0 cmd batch-file token

我的情况如下:

我已经在HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders文件夹位置下提取了一个注册表值.

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

我知道它与之相关,tokens但我希望有一种方法可以使代码适用于这两种情况.

我目前的代码如下:

FOR /F "tokens=2*" %I in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Startup ') DO echo "%J"
Run Code Online (Sandbox Code Playgroud)

和输出:

"%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"
Run Code Online (Sandbox Code Playgroud)

在旁注:扩展%USERPROFILE%对我来说没问题,我只是使用CALL函数

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

希望有人能够在两种情况下使其工作.

最诚挚的问候,

copyitright

MC *_* ND 5

for /f命令用法的一个要求是正确使用(在需要时)delimstokens子句.它们必须适当地适应正在处理的线的格式.

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

Cache    REG_EXPAND_SZ    %USERPROFILE%\AppData\Local\Microsoft\Windows\INetCache
My Pictures    REG_EXPAND_SZ    %USERPROFILE%\Pictures
Run Code Online (Sandbox Code Playgroud)

在第二行中,tokens当使用空格作为分隔符时,值名称中存在的附加空间需要不同的子句.

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

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

@echo off
    setlocal enableextensions disabledelayedexpansion

    for /f "skip=2 tokens=1,* delims=_" %%a in ('
        reg query 
            "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" 
            /v "My Pictures"
    ') do for /f "tokens=1,*" %%c in ("%%b") do echo "%%d"
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用另一种方法来检索值.您可以使用wmic查询注册表.像(对不起,西班牙语的地方)

W:\>wmic /NameSpace:\\root\default Class StdRegProv Call GetStringValue hDefKey="&H80000001" sSubKeyName="Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" sValueName="My Pictures"
Ejecutando (StdRegProv)->GetStringValue()
Ejecución correcta del método.
Parámetros de salida:
instance of __PARAMETERS
{
        ReturnValue = 0;
        sValue = "C:\\Users\\UserName\\Pictures";
};
Run Code Online (Sandbox Code Playgroud)

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

@echo off
    setlocal enableextensions disabledelayedexpansion    

    for /f tokens^=2^ delims^=^" %%a in ('
        WMIC /NameSpace:\\root\default Class StdRegProv 
            Call GetExpandedStringValue 
                hDefKey^="&H80000001" 
                sSubKeyName^="Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" 
                sValueName^="My Pictures" 
        ^| find "sValue"
    ') do echo "%%~fa"
Run Code Online (Sandbox Code Playgroud)

注意:wmic示例代码使用Shell Folders子键而不是User Shell Folders因为它wmic正在扩展%userprofile%system用户配置文件文件夹,我不确定这是否是默认/逻辑行为,或者它是我的机器中的问题.当我手头有另一台机器时,我会测试它.

  • @copyitright,a)如果要从定义的`*`标记中检索数据,则没有问题.问题是在左边创建额外令牌的空间将移动到`*`开始检索信息的位置.b)使用"用户外壳文件夹"进行调试,而不是使用另一个分支,例如.将您的价值观置于"HKCU \易变环境"下 (2认同)