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

问题描述 投票:0回答:2

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

[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 行上的两个值。

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

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

batch-file text-files
2个回答
1
投票

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

@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 以及所使用的选项会跳过文件的前三行。

第四行首先使用默认字符串分隔符、普通空格和水平制表符分成子字符串。第二个子字符串是

0x61
,它被分配给指定的循环变量
I
。第四行没有第三个子字符串。

IF条件检查在FOR

循环之上显式未定义的环境变量
Byte01是否仍未定义,在这种情况下,命令SET用于计算算术表达式,该表达式解释分配的字符串值0x61
到循环变量 
I
 作为十六进制值,并将该十进制值分配给环境变量 
Byte01

然后

FOR 处理第五行,使用空格/制表符作为分隔符再次将该行拆分为子字符串,并将第二个子字符串(标记)ACK

 分配给循环变量 
I
,将第三个子字符串 
0xA8
 分配给下一个但根据 
ASCII 表
有一个循环变量 
J

接下来再次执行

IF 条件,但这次 Byte01

 已经定义,导致使用命令 
SETELSE 命令块上继续进行批处理文件处理,用于计算算术表达式以定义环境变量Byte02
 将分配给循环变量 
J
 的十六进制值转换为十进制值 
AND 命令 GOTO 继续处理标签 Output
 下面的行上的批处理文件。这会导致在处理文件中的更多行之前退出循环。

要了解所使用的命令及其工作原理,请打开

命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

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

    有关
  • 使用命令重定向运算符的 Microsoft 文档
  • 使用 Windows 批处理文件的单行多个命令

1
投票
您甚至可以使用腰带和大括号,并使用

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

    

© www.soinside.com 2019 - 2024. All rights reserved.