我们假设您有一个文本文件,其中包含以下详细信息:
User1 ABCDEF
所以我想做的是将每个字符增加1,即输出应如下:
Vtfs2 BCDEFG
我想将这两个输出存储到两个不同的变量中,即:
Set var1=Vtfs2
Set var2=BCDEFG
我知道有一种使用for /f
的方法,但我还没到达那里。
以下是我能想出的所有内容:
for /f "tokens=* delims=" %%x in (Myfile.txt) do (
set var=%%x+1
)
但它的作用是以数字的形式加起来。那么我该如何将它应用于角色。
答案 0 :(得分:0)
for /F
用于读取和解析文本并将其拆分为标记,但它无法将字符转换为代码(ASCII)并返回。
我想到在字符串中获取字符代码的唯一方法是使用CertUtil
实用程序,该实用程序提供动词-encodehex
以将文本文件转换为十六进制编码的文件和动词-decodehex
进行相反的转换。由于这依赖于十六进制表示中的字符代码,并且手头的任务需要一些数学,我们需要进行十六进制到十进制的转换,反之亦然;前者可以通过set /A
实现,并且能够在以0x
为前缀时解释十六进制数字;后者可以使用名为=ExitCode
的未记录的内置变量来完成,该变量包含最新exit code的十六进制表示形式,而后者又可以由cmd
/C
设置exit
%NUMBER%
,其中%NUMBER%
是十进制退出代码(退出代码和ErrorLevel
并不总是相同,但在我们的情况下它们是)。
所以,让我们把所有这些东西放在一起吧:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set /A "_MIN=0x20" & rem // (minimal character code to regard for rotation)
set /A "_MAX=0x7F" & rem // (maximal character code to regard for rotation)
set "_TMP=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (path to temporary file)
rem // Convert provided rotation offset parameter to number:
set "OFFSET=%~3"
set /A "OFFSET+=0"
rem // Convert input text file to temporary hexadecimal-encoded file:
> nul CertUtil -encodehex "%~1" "%_TMP%" || (
>&2 echo The system cannot find the file specified.
exit /B 1
)
rem // Read temporary hexadecimal-encoded file, then clear it:
for /F "tokens=1,* delims= " %%K in ('type "%_TMP%" ^& ^> "%_TMP%" rem/') do (
rem // Get line with the preceding position number removed:
set "NEW= " & set "LINE=%%L"
setlocal EnableDelayedExpansion
rem // Iterate through all character codes of the current line:
for %%K in (!LINE:~^,48!) do (
rem // Retrieve a single character code as decimal number:
set /A "CODE=0x%%K"
rem // Check whether character code is in applicable range:
if !CODE! GEQ %_MIN% if !CODE! LEQ %_MAX% (
rem /* Perform rotation by adding the given offset;
rem adapt result if predefined range is left: */
set /A "CODE+=OFFSET%%(1+_MAX)"
if !CODE! LSS %_MIN% set /A "CODE+=1+_MAX-_MIN"
if !CODE! GTR %_MAX% set /A "CODE-=1+_MAX-_MIN"
)
rem /* Convert rotated character code to hexadecimal number,
rem collect the character codes in a single line: */
cmd /C exit !CODE!
set "NEW=!NEW!!=ExitCode:~-2! "
)
rem // Write line of collected character codes to temporary file:
>> "%_TMP%" echo(!NEW:~1,-1!
endlocal
)
rem // Convert temporary hexadecimal-encoded file to output text file:
> nul CertUtil -f -decodehex "%_TMP%" "%~2" || (
>&2 echo The system cannot find the path specified.
exit /B 1
)
rem // Clean up temporary file:
del "%_TMP%"
endlocal
exit /B
这个脚本 - 我们称之为rotate-chars.bat
- 需要三个命令行参数:输入文本文件的路径,输出文本文件的路径(可能与输入文件的路径相同)直接修改它)和旋转字符代码的数量(根据你的问题,这应该设置为+1
)。因此,当使用以下命令行调用脚本时......:
rotate-chars.bat "test.txt" "test_NEW.txt" +1
...并且具有以下test.txt
...:
User1 ABCDEF
...,临时文件在脚本中首次执行CertUtil
后立即保存以下内容:
0000 55 73 65 72 31 0d 0a 41 42 43 44 45 46 0d 0a User1..ABCDEF..
执行for /F
循环后,临时文件包含:
56 74 66 73 32 0D 0A 42 43 44 45 46 47 0D 0A
您可以看到每个字符代码都增加了一个,除了脚本顶部给出的范围之外(0x20
到0x7F
;外部任何代码都没有触及)。省略了初始位置(0000
)和最终文本列,因为它们不需要进行反向转换。
在第二次执行CertUtil
之后,返回的输出文件test_NEW.txt
将包含以下数据:
Vtfs2 BCDEFG
请注意,如果字符代码在一个边界处移出指定范围,例如0x7E
+ 5
= 0x83
,其边界为0x20
和{{ 1}},它移到了另一端,如0x7F
(= 0x23
- (0x83
+ 1)+ 0x7F
);这就是使用术语“轮换”的原因。
要将生成的文本文件的前两行存储到变量中,您可以执行以下操作:
0x20