Reputation: 25
I have a text file of data that I want to extract a couple values from specific locations on specific lines.
[0xA1 rr]
I2C START BIT
WRITE: 0xA1 ACK
READ: 0x61
READ: ACK 0xA8
NACK
I2C STOP BIT
I2C>
I2C>
In the above file, I want to take the '61' on the 4th line, and the 'A8' on the 5th line. The values after the '0x' change but are always two characters in the same locations (which I'll then combine and convert from Hex to Decimal).
It seems I can take an entire specific line with something like the following code:
for /F "skip=3 delims=" %%i in ("%FileName%") set "Line04=%%i"
and I can take values from after specific characters with something like the following code:
FOR /f "usebackqtokens=1*delims=:" %%a IN ("%FileName%") DO (
IF "%%a"=="0x" SET /a Byte01=%%b
)
But I don't need all the values after '0x' just the two on lines 4 and 5.
I'm having trouble joining these commands together to take just the required two characters from each of the two lines.
Can anyone help me put all these pieces (or other pieces I haven't figured out) together to pull these values I need out of the file?
Upvotes: 1
Views: 939
Reputation: 49086
The two byte values can be read from the file as demonstrated by the following code:
@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
The command FOR with the used options skips the first three lines of the file.
The fourth line is first split up into substrings using the default string delimiters normal space and horizontal tab. The second substring is 0x61
which is assigned to the specified loop variable I
. There is no third substring on fourth line.
The IF condition checks if the environment variable Byte01
explicitly undefined above the FOR loop is still not defined in which case the command SET is used to evaluate an arithmetic expression which interprets the string value 0x61
assigned to the loop variable I
as hexadecimal value and assigns this value in decimal to the environment variable Byte01
.
Then FOR processes the fifth line with splitting the line up once again into substrings using space/tab as delimiters and assigns the second substring (token) ACK
to loop variable I
and the third substring 0xA8
to next but one loop variable J
according to the ASCII table.
There is executed next once again the IF condition, but this time Byte01
is already defined resulting in continuing batch file processing on ELSE command block with command SET used to evaluate the arithmetic expression to define the environment variable Byte02
with the hexadecimal value assigned to loop variable J
converted to a decimal value AND command GOTO to continue processing of the batch file on the line below the label Output
. That results in exiting the loop before it processes more lines from the file.
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
call /?
... explains %~n0
(name of argument 0 which is the batch file name)del /?
echo /?
endlocal /?
for /?
if /?
set /?
setlocal /?
See also:
Upvotes: 1
Reputation: 38579
You could even go belt and braces, and use FindStr
to isolate only the lines which begin with READ:
and end with 0xNN
, (where NN
is a base 16 hex pair).
You would however need to confirm that because some of the lines in your posted content have non consistent trailing whitespace!
@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
Don't forget to change your input file on line 3
before testing it.
BTW, you could even convert each of those hex pairs to decimal:
by changing Set "Byte[%%H]=%%G"
to Set /A Byte[%%H] = 0x%%G
Upvotes: 1