我有一个字符串
"AABBCCDDEEF0011223344556677889900"
我想在每个其他角色之间添加一个空格,以便我的输出如下:
"AA BB CC DD EE FF 00 11 22 33 44 55 66 77 88 99 00"
我需要对windows批处理文件中的变量执行此操作:
set HEX=AABBCCDDEEF0011223344556677889900
<-- YOUR CODE -->
echo %HEX%
//outputs AA BB CC DD EE FF 00 11 22 33 44 55 66 77 88 99 00
这个示例脚本怎么样?
在此示例中,在从HEX
的第一个字符中检索到2个字符后,将从HEX
中删除2个字符。这一直重复到HEX
结束。
@ECHO OFF
SETLOCAL
SET "HEX=AABBCCDDEEFF0011223344556677889900"
:LOOP
IF NOT "%HEX%"=="" (
SET "RES=%RES%%HEX:~0,2% "
SET "HEX=%HEX:~2%"
GOTO :LOOP
)
ECHO "%RES:~0,-1%"
"AA BB CC DD EE FF 00 11 22 33 44 55 66 77 88 99 00"
有"AABBCCDDEEF0011223344556677889900"
有问题。它只有一个F
。但"AA BB CC DD EE FF 00 11 22 33 44 55 66 77 88 99 00"
是你想要的。预期结果有FF
。所以在我的示例脚本中,我使用了SET "HEX=AABBCCDDEEFF0011223344556677889900"
。
如果这对你没用,我很抱歉。
@ECHO OFF
SETLOCAL
SET "HEX=AABBCCDDEEFF0011223344556677889900"
:LOOP
SET "RES=%RES%%HEX:~0,2% "
SET "HEX=%HEX:~2%"
IF DEFINED HEX GOTO LOOP
ECHO "%RES:~0,-1%"
根据@Magoo的建议,示例脚本已更新。非常感谢。
使用不恰当的技术是一个相当不合适
Set TempStr=AABBCCDDEEF0011223344556677889900
Set Str=%tempstr:~0,2% %tempstr:~2,2% %tempstr:~4,2% %tempstr:~6,2% [et al]
Echo %Str%
使用纯批处理(它应该很快,因为它不依赖于标签来模拟循环,但计算脚本长度并使用for /l
循环):
@echo off
:::::::::: tests ::::::::::
call :funct aabb0103 hex
echo %hex%
call :funct AAFFEE00
exit /b %errorlevel%
::::::::::::::::::::::::
:funct
@echo off
setlocal enableDelayedExpansion
set "str=%~1"
set LF=^
rem ** Two empty lines are required
setlocal DisableDelayedExpansion
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
set $strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n%
for /F "tokens=1,2 delims=, " %%1 in ("!argv!") do (%\n%
set "str=A!%%~2!"%\n%
set "len=0"%\n%
for /l %%A in (12,-1,0) do (%\n%
set /a "len|=1<<%%A"%\n%
for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"%\n%
)%\n%
for %%v in (!len!) do endlocal^&if "%%~b" neq "" (set "%%~1=%%v") else echo %%v%\n%
) %\n%
) ELSE setlocal enableDelayedExpansion ^& set argv=,
%$strlen% strlen,str
set "res="
setlocal enableDelayedExpansion
for /l %%i in (0,1,%strlen%) do (
set /a check=%%i %% 2
if !check! == 0 if "!str:~%%i,1!" neq "" (
set "res=!res!!str:~%%i,1!"
)
if !check! == 1 if "!str:~%%i,1!" neq "" (
set "res=!res!!str:~%%i,1! "
)
)
endlocal & endlocal & endlocal & if "%~2" NEQ "" (
set "%~2=%res%"
) else (
echo %res%
)
exit /b 0
JSCript hybrid - 您可以将其称为单独的.bat
文件。它所采用的唯一参数是十六进制字符串:
@if (@X)==(@Y) @end /* JScript comment
@echo off
cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%
@if (@X)==(@Y) @end JScript comment */
var hex=WScript.Arguments.Item(0);
var res="";
for ( var i = 0; i < hex.length; ++i){
if(( i % 2)==0) {
res+=hex.charAt(i);
} else {
res+=hex.charAt(i)+' ';
}
}
WScript.Echo(res);
在PowerShell中执行此操作的方法。使用额外的空格字符克服了字符串中奇数个字符的问题。
PS C:\src\t> $ss = 'AABBCCDDEEFF0011223344556677889900'
PS C:\src\t> $v = for ($i=0; $i -lt $ss.Length; $i += 2) { ($ss + ' ').Substring($i,2) }
PS C:\src\t> $v -join(' ')
AA BB CC DD EE FF 00 11 22 33 44 55 66 77 88 99 00
如果必须在cmd.exe中执行此操作:
C:>powershell -NoProfile -Command "$ss = 'AABBCCDDEEFF0011223344556677889900'; $v = for ($i=0; $i -lt $ss.Length; $i += 2) { ($ss + ' ').Substring($i,2) }; $v -join(' ')"
AA BB CC DD EE FF 00 11 22 33 44 55 66 77 88 99 00
或者,使用变量:
C:>SET "SS=AABBCCDDEEFF0011223344556677889900"
C:>powershell -NoProfile -Command "$ss = '%SS%'; $v = for ($i=0; $i -lt $ss.Length; $i += 2) { ($ss + ' ').Substring($i,2) }; $v -join(' ')"
AA BB CC DD EE FF 00 11 22 33 44 55 66 77 88 99 00
我很确定之前曾经问过并回答过,但不幸的是我找不到它。
这是另一种替代的纯批处理文件:
@Echo Off
SetLocal EnableDelayedExpansion
Set "HEX=AABBCCDDEEF0011223344556677889900"
Set "_i=0"
For /F Delims^=^ EOL^= %%A In ('CMD/U/CEcho^=%HEX%^|Find /V ""') Do (
Set/A "_i+=1, _m=_i%%2"
If !_m! Equ 0 (Set "_s=!_s!%%A ") Else Set "_s=!_s!%%A")
If %_m% Equ 0 Set "_s=%_s:~,-1%"
Echo=%_s%
Timeout -1
......还有一个利用PowerShell:
@Echo Off
SetLocal EnableDelayedExpansion
Set "HEX=AABBCCDDEEF0011223344556677889900"
Set "PAIRS="
For /F %%A In ('PowerShell -C "'%HEX%' -Split '(..)'|?{$_}"') Do Set "PAIRS=!PAIRS! %%A"
Echo %PAIRS:~1%
Timeout -1
这是一个简短快速的纯批处理解决方案,可以避免任何GOTO循环
@echo off
setlocal enableDelayedExpansion
set "hex=AABBCCDDEEFF0011223344556677889900"
set "out="
for /l %%N in (0,2,8191) do if "!hex:~%%N!" equ "" (goto :done) else set "out=!out!!hex:~%%N,2! "
:done
set "hex=!out:~0,-1!"
echo [!hex!]
这是与可调用函数相同的逻辑:
@echo off
setlocal
set "hex=AABBCCDDEEFF0011223344556677889900"
:: Simply print the result
call :formatHex hex
:: Store the result back in hex
call :formatHex hex hex
echo [%hex%]
exit /b
:formatHex InVar [OutVar]
:: Add space between hex pairs found in variable InVar.
:: Store the result in OutVar.
:: If OutVar is not specified, then ECHO the result
::
setlocal enableDelayedExpansion
set "in=.!%~1!" In case InVar is undefined, add a character in the front and start the loop at 1 instead of 0
set "out="
for /l %%N in (1,2,8191) do if "!in:~%%N!" equ "" (goto :done) else set "out=!out!!in:~%%N,2! "
:done
if defined out set "out=!out:~0,-1!"
endlocal & if "%~2" equ "" (echo(%out%) else set "%~2=%out%"
exit /b
如果你有JREPL.BAT - a hybrid JScript/batch regular expression text processing utility,那么你可以简单地使用:
call jrepl "..(?=.)" "$& " /m /s hex /rtn hex
但是由于CSCRIPT引擎的启动时间,JREPL解决方案会变慢。