簡體   English   中英

批處理文件:如何替換“=”(等號)和字符串變量?

[英]Batch file: How to replace “=” (equal signs) and a string variable?

除了SED,如何更換等號? 如何在字符串替換中使用字符串變量?

考慮這個例子:

For /F "tokens=*" %%B IN (test.txt) DO (
   SETLOCAL ENABLEDELAYEDEXPANSION
   SET t=is
   SET old=%%B
   SET new=!old:t=!
   ECHO !new!

   ENDLOCAL
)

:: SET new=!old:==!

兩個問題:

首先,我不能在!:=!中使用變量%t%。

   SET t=is
   SET old=%%B
   SET new=!old:t=!

其次,我無法替換命令行中的等號

   SET new=!old:==!

我剛剛為此創建了一個簡單的解決方案,也許它可以幫到某個人。

缺點(或優勢,取決於你想要做什么)是一個接一個地處理多個等號,就像一個單一的等號。 (例如:“str == ing”給出與“str = ing”相同的輸出)

@echo off
set "x=this is=an test="
echo x=%x%

call :replaceEqualSign in x with _
echo x=%x%

pause&exit


:replaceEqualSign in <variable> with <newString>
    setlocal enableDelayedExpansion

        set "_s=!%~2!#"
        set "_r="

        :_replaceEqualSign
            for /F "tokens=1* delims==" %%A in ("%_s%") do (
                if not defined _r ( set "_r=%%A" ) else ( set "_r=%_r%%~4%%A" )
                set "_s=%%B"
            )
        if defined _s goto _replaceEqualSign

    endlocal&set "%~2=%_r:~0,-1%"
exit /B

如您所見,您使用如下函數:

call :replaceEqualSign in variableName with newString

如果%% B包含舊的= %% B分配,則應移動setlocal enableDelayedExpansion !

通過使用另一個FOR變量,“t”問題很容易在循環內解決

For /F "tokens=*" %%B IN (test.txt) DO (
   SET t=is
   SET old=%%B
   SETLOCAL ENABLEDELAYEDEXPANSION
   for /f %%T in ("!t!") do SET new=!old:%%T=!
   ECHO !new!
   ENDLOCAL
)

替換=沒有簡單的本地批處理解決方案。 你可以逐個字符地遍歷字符串,但這很慢。 您最好的選擇可能是切換到VBScript或JScript,或使用非本機實用程序。

如果您真的想使用純Windows批處理命令執行此操作,請參閱http://www.dostips.com/forum/viewtopic.php?t=1485上的一些有趣的想法

更新 :最新版本的腳本在這里: https//sf.net/p/contools (腳本在這里: https//sf.net/p/contools/contools/HEAD/tree/trunk/Scripts/Tools/std /

您可以使用某些序列來臨時替換占位符,例如?00,?01,?02和?03。 我基本上使用這些腳本集:

replace_sys_chars.bat:

@echo off

rem Description:
rem   Script to replace ?, !, %, and = characters in variables by respective
rem   ?00, ?01, ?02 and ?03 placeholders.

setlocal DISABLEDELAYEDEXPANSION

set "__VAR__=%~1"

if "%__VAR__%" == "" exit /b 1

rem ignore empty variables
call set "STR=%%%__VAR__%%%"
if "%STR%" == "" exit /b 0

set ?01=!

call set "STR=%%%__VAR__%:?=?00%%"
set "STR=%STR:!=?01%"

setlocal ENABLEDELAYEDEXPANSION

set STR=!STR:%%=?02!
set "STR_TMP="
set INDEX=1

:EQUAL_CHAR_REPLACE_LOOP
set "STR_TMP2="
for /F "tokens=%INDEX% delims== eol=" %%i in ("/!STR!/") do set STR_TMP2=%%i
if "!STR_TMP2!" == "" goto EQUAL_CHAR_REPLACE_LOOP_END
set "STR_TMP=!STR_TMP!!STR_TMP2!?03"
set /A INDEX+=1
goto EQUAL_CHAR_REPLACE_LOOP

:EQUAL_CHAR_REPLACE_LOOP_END
if not "!STR_TMP!" == "" set STR=!STR_TMP:~1,-4!

(
  endlocal
  endlocal
  set "%__VAR__%=%STR%"
)

exit /b 0

restore_sys_chars.bat:

@echo off

rem Description:
rem   Script to restore ?, !, %, and = characters in variables from respective
rem   ?00, ?01, ?02 and ?03 placeholders.

setlocal DISABLEDELAYEDEXPANSION

set "__VAR__=%~1"

if "%__VAR__%" == "" exit /b 1

rem ignore empty variables
call set "STR=%%%__VAR__%%%"
if "%STR%" == "" exit /b 0

setlocal ENABLEDELAYEDEXPANSION

set STR=!STR:?02=%%!
set STR=!STR:?03==!

(
  endlocal
  set "STR=%STR%"
)

set "STR=%STR:?01=!%"
set "STR=%STR:?00=?%"

(
  endlocal
  set "%__VAR__%=%STR%"
)

exit /b 0

例:

@echo off

setlocal DISABLEDELAYEDEXPANSION

for /F "usebackq tokens=* delims=" %%i in ("test.txt") do (
  set VALUE=%%i
  call :PROCESS
)
exit /b 0

:PROCESS
if "%VALUE%" == "" exit /b 0

set "VALUE_=%VALUE%"
call replace_sys_chars.bat VALUE_

rem do variable arithmetic here as usual
if not "%VALUE_:?00=%" == "%VALUE_%" echo."%VALUE%" having ?
if not "%VALUE_:?01=%" == "%VALUE_%" echo."%VALUE%" having !
if not "%VALUE_:?02=%" == "%VALUE_%" echo."%VALUE%" having %%
if not "%VALUE_:?03=%" == "%VALUE_%" echo."%VALUE%" having =

rem restore it
call restore_sys_chars.bat VALUE_
echo "VALUE=%VALUE_%"

echo.---

的test.txt:

111/222
AAA=BBB
CCC=%DDD%
EEE=!FFF!
FFF=?00?01?02?03

結果:

"VALUE=111/222"
---
"AAA=BBB" having =
"VALUE=AAA=BBB"
---
"CCC=%DDD%" having %
"CCC=%DDD%" having =
"VALUE=CCC=%DDD%"
---
"EEE=!FFF!" having !
"EEE=!FFF!" having =
"VALUE=EEE=!FFF!"
---
"FFF=?00?01?02?03" having ?
"FFF=?00?01?02?03" having =
"VALUE=FFF=?00?01?02?03"
---

特點

  • 您可以在轉換之間繼續使用標准批量變量算法
  • 您可以使用字符占位符(?00,?01,?02,?03)作為普通變量值

為什么不使用Edlin? 我找不到用一個初始文件做這個的方法而且Edlin沒有錯誤,但是用NUL忽略它們: 扼殺,即使在=和!之間存在文件結尾字符,TYPE%0也包含整個文件,在運行后使用批處理文件上的TYPE將不會以相同的方式工作。

@ECHO OFF
GOTO skip
1,1r=!
e
:skip

SET "new==old============="

ECHO %new% > %TEMP%\var.tmp
TYPE %0 > %TEMP%\edlin.tmp

EDLIN %TEMP%\var.tmp < %TEMP%\edlin.tmp > NUL:

SET /P newnew=<%TEMP%\VAR.TMP
ECHO %newnew%

ERASE %TEMP%\VAR.TMP
ERASE %TEMP%\VAR.BAK
ERASE %TEMP%\edlin.tmp

我在另一篇文章中的回答,但也適用於此:

還有一種更容易的選擇。 而不是傳入包含等號的值,而是嘗試使用冒號。 然后,通過修改該值(冒號)的能力,您可以將其轉換回等於。 這是一個例子:

@echo off
set VALUE1=%1
set VALUE2=%VALUE1::==%
echo value1 = %VALUE1%
echo value2 = %VALUE2%

運行批處理文件時,請按以下方式調用它:

C:\>myBatch name:someValue

輸出將是:

value1 = name:someValue
value2 = name=someValue

如果名稱或值包含空格,則還需要解決其他問題。 您需要將整個字符串用雙引號括起來。 但是,那么你有需要擺脫它們的問題。 這也可以處理,如下所示:

@echo off
cls
set PARAM=%1
set BASE=%PARAM:"=%
set PAIR=%BASE::==%

rem Either of these two lines will do the same thing - just notice the 'delims'
rem for /f "tokens=1,2 delims=:" %%a in ("%BASE%") do set NAME=%%a & set VALUE=%%b
rem for /f "tokens=1,2 delims==" %%a in ("%PAIR%") do set NAME=%%a & set VALUE=%%b

for /f "tokens=1,2 delims=:" %%a in ("%BASE%") do set NAME=%%a & set VALUE=%%b

echo param = %PARAM%
echo base  = %BASE%
echo pair  = %PAIR%
echo name  = %NAME%
echo value = %VALUE%

運行此批處理文件時,如下所示:

C:\>myBatch "some name:another value"

輸出將是:

param = "some name:another value"
base  = some name:another value
pair  = some name=another value
name  = some name
value = another value

希望幫助其他人在他們的任務中贏得與批處理文件的斗爭。

邁克五世

我正在研究這個問題,因為我需要在像“test = goingon”這樣的字符串中刪除=我發現調用下一個使用test = goon作為參數的批處理文件,我有參數1,“test”和2,“goon “,在該批處理文件中。

所以:batchfile 1:

@echo off
call test2.bat test=goingon

batchfile2:

echo arg1: %1
echo arg2: %2

結果:

arg1: test
arg2: goingon

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM