【问题标题】:identify or delete equal sign (=) in Windows command script environment variable识别或删除 Windows 命令脚本环境变量中的等号 (=)
【发布时间】:2017-01-30 01:18:22
【问题描述】:

有没有办法做这个主题?例如,我们不能简单地通过子字符串替换语法%variable:substring1=substring2%来替换等号,因为substring1不能包含等号。

【问题讨论】:

    标签: batch-file cmd environment-variables escaping special-characters


    【解决方案1】:

    这是一种方法(想法是用 for /f 拆分它,并用相同数量的替换替换等号,用 strlen 函数计算它们的长度):

    @echo off
    
    
    rem ===== testing the function =======
    
    set "eqs====abcd=abcd===abcdabcd======~*"
    set replace_with=X1
    echo %eqs%
    
    call :eqreplacer "%eqs%" %replace_with% res
    echo %res%
    exit /b %errorlevel%
    
    rem ===============================
    
    
    :eqreplacer String Replacer [RtnVar]
    setlocal
    rem  the result of the operation will be stored here
    set "result=#%~1#"
    set "replacer=%~2"
    call :strlen0  result wl
    call :strlen0  replacer rl
    
    :start
    
      set "part1="
      set "part2="
    
      rem splitting the string on two parts
      for /f "tokens=1* delims==" %%w in ("%result%") do (
       set "part1=%%w"
       set "part2=%%x"
      )
    
      rem calculating the count replace strings we should use
      call :strlen0  part1 p1l
      call :strlen0  part2 p2l
      set /a iteration_end=wl-p1l-p2l
    
      rem creating a sequence with replaced strings
      setlocal enableDelayedExpansion
      set "sequence="
      for /l %%i in (1,1,%iteration_end%) do (
       set sequence=!sequence!%replacer%
      )
      endlocal & set "sequence=%sequence%"
    
      rem adjust the string length
      set /a wl=wl+iteration_end*(rl-1)
    
      rem replacing for the current iteration
      set result=%part1%%sequence%%part2%
      rem if the second part is empty the task is over
      if "%part2%" equ "" (
       set result=%result:~1,-1%
       goto :endloop
      )
    
    
      goto :start
    
    :endloop
    endlocal & if "%~3" neq "" (set %~3=%result%) else echo %result%
    exit /b
    
    :strlen0  StrVar  [RtnVar]
      setlocal EnableDelayedExpansion
      set "s=#!%~1!"
      set "len=0"
      for %%N in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
        if "!s:~%%N,1!" neq "" (
          set /a "len+=%%N"
          set "s=!s:~%%N!"
        )
      )
      endlocal&if "%~2" neq "" (set %~2=%len%) else echo %len%
    exit /b
    

    here you can find more solutions.看看dbenham的post

    【讨论】:

      【解决方案2】:

      识别=的简单方法。

      echo "%variable%"|find "=">nul
      if not errorlevel 1 echo equal sign detected
      

      【讨论】:

        【解决方案3】:

        一个遍历字符串并根据=检查每个字符的简单循环怎么样?

        @echo off
        setlocal EnableExtensions DisableDelayedExpansion
        
        rem // Define constants here:
        set "STRING=%~1" & rem // (string from first command line argument)
        set "SEARCH==" & rem // (specify a single character here)
        set "REPLAC=" & rem // (specify an arbitrary string here)
        
        rem // Check search string for validity (one character):
        if not defined SEARCH ((>&2 echo ERROR: no search string defined!) & exit /B 1)
        setlocal EnableDelayedExpansion
        if not "!SEARCH:~1!"=="" ((>&2 echo ERROR: search string too long^^!) & exit /B 1)
        rem // Loop through each character of the string:
        set "RESULT="
        :LOOP
        if not defined STRING goto :QUIT
        rem // Compare current character with search string:
        set "CHAR=!STRING:~,1!"
        if "!CHAR!"=="!SEARCH!" (
            rem // Match found, so replace character:
            set "RESULT=!RESULT!!REPLAC!"
        ) else (
            rem // No match found, so keep character:
            set "RESULT=!RESULT!!CHAR!"
        )
        rem // Remove processed character from (remaining) string:
        set "STRING=!STRING:~1!"
        goto :LOOP
        :QUIT
        rem // Return result here finally:
        echo(!RESULT!
        endlocal
        
        endlocal
        exit /B
        

        这在性能方面应该会好一点,因为字符串操作较少:

        @echo off
        setlocal EnableExtensions DisableDelayedExpansion
        
        rem // Define constants here:
        set "STRING=%~1" & rem // (string from first command line argument)
        set "SEARCH==" & rem // (specify a single character here)
        set "REPLAC=" & rem // (specify an arbitrary string here)
        
        rem // Check search string for validity (one character):
        if not defined SEARCH ((>&2 echo ERROR: no search string defined!) & exit /B 1)
        setlocal EnableDelayedExpansion
        if not "!SEARCH:~1!"=="" ((>&2 echo ERROR: search string too long^^!) & exit /B 1)
        rem // Loop through each character of the string:
        set /A "INDEX=0" & set "RESULT="
        if not defined STRING goto :QUIT
        :LOOP
        rem // Compare currently indexed character with search string:
        set "CHAR=!STRING:~%INDEX%,1!"
        if not defined CHAR goto :QUIT
        if "!CHAR!"=="!SEARCH!" (
            rem // Match found, so replace character:
            set "RESULT=!RESULT!!REPLAC!"
        ) else (
            rem // No match found, so keep character:
            set "RESULT=!RESULT!!CHAR!"
        )
        rem // Increment character index:
        set /A "INDEX+=1"
        goto :LOOP
        :QUIT
        rem // Return result here finally:
        echo(!RESULT!
        endlocal
        
        endlocal
        exit /B
        

        【讨论】:

        • 为什么要使用延迟扩展?有必要吗?如果是,在哪里不能用常规的%reference% 替换,为什么?
        • 我使用它主要是为了避免在输入字符串中出现"时出现问题;在正常(立即)扩展的情况下,几个命令行被破坏了......
        猜你喜欢
        • 2010-09-23
        • 1970-01-01
        • 2023-01-15
        • 2017-06-13
        • 2016-12-13
        • 1970-01-01
        • 1970-01-01
        • 2019-03-30
        • 2013-03-29
        相关资源
        最近更新 更多