如何使用批处理文件从文件中的特定行读取特定字符?

How to read specific characters from specific lines in file with batch file?

我有一个数据文本文件,我想从特定行的特定位置提取几个值。

[0xA1 rr] 
I2C START BIT
WRITE: 0xA1 ACK 
READ: 0x61 
READ:  ACK 0xA8 
NACK
I2C STOP BIT
I2C>
I2C>

在上面的文件中,我想取第4行的'61'和第5行的'A8'。 '0x' 之后的值发生变化,但始终是相同位置的两个字符(然后我会将它们合并并从十六进制转换为十进制)。

看来我可以用类似下面的代码来获取完整的特定行:

for /F "skip=3 delims=" %%i in ("%FileName%") set "Line04=%%i"

我可以使用类似以下代码的特定字符后取值:

FOR /f "usebackqtokens=1*delims=:" %%a IN ("%FileName%") DO (
 IF "%%a"=="0x" SET /a Byte01=%%b
)

但我不需要“0x”之后的所有值,只需要第 4 行和第 5 行的两个值。

我无法将这些命令连接在一起以从两行中的每一行中仅获取所需的两个字符。

任何人都可以帮我把所有这些部分(或其他我还没弄清楚的部分)放在一起,从文件中提取我需要的这些值吗?

可以从文件中读取两个字节值,如下面的代码所示:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FileName=%TEMP%\%~n0.tmp"
(
echo [0xA1 rr]
echo I2C START BIT
echo WRITE: 0xA1 ACK
echo READ: 0x61
echo READ:  ACK 0xA8
echo NACK
echo I2C STOP BIT
echo I2C^>
echo I2C^>
)>"%FileName%"

set "Byte01="
set "Byte02="
for /F "usebackq skip=3 tokens=2,3" %%I in ("%FileName%") do if not defined Byte01 (set /A "Byte01=%%I") else (set /A "Byte02=%%J" & goto Output)

:Output
if defined Byte01 (
    echo The byte values are:
    echo/
    set Byte
)
del "%FileName%"
endlocal

使用选项的命令 FOR 跳过文件的前三行。

第四行首先使用默认字符串定界符正常 space 和水平制表符拆分为子字符串。第二个子字符串是 0x61,它被分配给指定的循环变量 I。第四行没有第三个子串。

IF 条件检查在 FOR 循环上面是否仍未定义环境变量 Byte01 显式未定义 which如果命令 SET 用于评估算术表达式,该表达式将分配给循环变量 I 的字符串值 0x61 解释为十六进制值,并以十进制形式分配该值到环境变量 Byte01.

然后 FOR 处理第五行,使用 space/tab 作为分隔符再次将该行拆分为子字符串,并分配第二个子字符串(标记)ACK 循环变量 I 和第三个子字符串 0xA8 到下一个但根据 ASCII table.

的一个循环变量 J

接下来会再次执行 IF 条件,但这次 Byte01 已经定义,导致在 ELSE[ 上继续批处理文件处理=76=] 命令块与命令 SET 用于评估算术表达式来定义环境变量 Byte02 将十六进制值分配给循环变量 J 转换为十进制值 AND 命令 GOTO 继续处理标签 Output 下方行上的批处理文件。这导致在处理文件中的更多行之前退出循环。

要了解使用的命令及其工作原理,请打开 command prompt window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • call /? ... 解释 %~n0(参数 0 的名称,即批处理文件名)
  • del /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • set /?
  • setlocal /?

另请参阅:

您甚至可以使用腰带和大括号,并使用 FindStr 仅隔离以 READ: 开头并以 0xNN 结尾的行(其中 NN 是以 16 为底的十六进制对).

但是您需要确认这一点,因为您发布的内容中的某些行具有不一致的尾随空格!

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "FileName=C:\Users\NFM\Desktop\output.log"
For /F "Delims==" %%G In ('"(Set Byte[) 2>NUL"') Do Set "%%G="
If Not Exist "%FileName%" (Exit /B) Else Set "i=0"
For /F "Tokens=2 Delims=x" %%G In ('%SystemRoot%\System32\findstr.exe
 /RC:"^READ: [ACK ]*0x[0123456789ABCDEF][0123456789ABCDEF]$" "%FileName%"'
) Do (Set /A i += 1 & SetLocal EnableDelayedExpansion
    For %%H In (!i!) Do EndLocal & Set "Byte[%%H]=%%G")
Rem Example line to show you any variables defined with their values.
(Set Byte[) 2>NUL && Pause

在测试之前不要忘记在第 3 行更改输入文件。

顺便说一句,您甚至可以将每个十六进制对转换为十进制:
通过将 Set "Byte[%%H]=%%G" 更改为 Set /A Byte[%%H] = 0x%%G