我正在使用非常大的FIX消息日志文件。每条消息代表一组由SOH字符分隔的标签。
与MQ消息不同,单个FIX标记(和整体消息)不具有固定长度或位置。日志可以包括不同类型的消息(具有不同数量和标签序列)。
示例(多种消息之一):
07:00:32 -SEND:8=FIX.4.0(SOH)9=55(SOH)35=0(SOH)34=2(SOH)43=N(SOH)52=20120719-11:00:32(SOH)49=ABC(SOH)56=XYZ(SOH)10=075
所以唯一确定的事情如下:(1)带有等号的标签号唯一标识标签,(2)标签由SOH字符分隔。
对于特定的标签(一次只是其中几个,而不是所有标签),我需要得到一个不同值的列表 - 如下所示:
49 = ABC 49 = DEF 49 = GHI ......
输出的格式并不重要。
我非常感谢任何建议和建议。
亲切的问候, Victor O。
答案 0 :(得分:2)
选项1
下面的批处理脚本具有不错的性能。它有以下限制
=
的所有值
编辑 - 我的原始代码根本不支持值=
。我通过在变量名中添加额外的SOH字符来减少该限制,并更改了用于解析值的delim。现在,只要在=
之前区分唯一值,值就可以包含=
。如果值在=
之后区分,则只保留一个值。
务必将SOH变量的定义固定在顶部附近。
日志文件的名称作为第一个参数传递,请求的标记列表作为第二个参数传递(用引号括起来)。
@echo off
setlocal disableDelayedExpansion
:: Fix the definition of SOH before running this script
set "SOH=<SOH>"
set LF=^
:: The above 2 blank lines are necessary to define LF, do not remove.
:: Make sure there are no existing tag_ variables
for /f "delims==" %%A in ('2^>nul set tag_') do set "%%A="
:: Read each line and replace SOH with LF to allow iteration and parsing
:: of each tag/value pair. If the tag matches one of the target tags, then
:: define a tag variable where the tag and value are incorporated in the name.
:: The value assigned to the variable does not matter. Any given variable
:: can only have one value, so duplicates are removed.
for /f "usebackq delims=" %%A in (%1) do (
set "ln=%%A"
setlocal enableDelayedExpansion
for %%L in ("!LF!") do set "ln=!ln:%SOH%=%%~L!"
for /f "eol== tokens=1* delims==" %%B in ("!ln!") do (
if "!!"=="" endlocal
if "%%C" neq "" for %%D in (%~2) do if "%%B"=="%%D" set "tag_%%B%SOH%%%C%SOH%=1"
)
)
:: Iterate the defined tag_nn variables, parsing out the tag values. Write the
:: values to the appropriate tag file.
del tag_*.txt 2>nul
for %%A in (%~2) do (
>"tag_%%A.txt" (
for /f "tokens=2 delims=%SOH%" %%B in ('set tag_%%A') do echo %%B
)
)
:: Print out the results to the screen
for %%F in (tag_*.txt) do (
echo(
echo %%F:
type "%%F"
)
选项2
这个脚本几乎没有任何限制,但速度明显变慢。我可以看到的唯一限制是它不允许以=
开头的值(前导=
将被丢弃)。
我创建了一个临时的“search.txt”文件,用于FINDSTR / G:选项。由于FINDSTR限制,我使用文件而不是命令行搜索字符串。命令行搜索字符串不能匹配多个字符&gt;十进制128.此外,文字反斜杠的转义规则在命令行上不一致。有关详细信息,请参阅What are the undocumented features and limitations of the Windows FINDSTR command?。
必须再次修复SOH定义,第一个和第二个参数与第一个脚本相同。
@echo off
setlocal disableDelayedExpansion
:: Fix the definition of SOH before running this script
set "SOH="
set lf=^
:: The above 2 blank lines are necessary to define LF, do not remove.
:: Read each line and replace SOH with LF to allow iteration and parsing
:: of each tag/value pair. If the tag matches one of the target tags, then
:: check if the value already exists in the tag file. If it doesn't exist
:: then append it to the tag file.
del tag_*.txt 2>nul
for /f "usebackq delims=" %%A in (%1) do (
set "ln=%%A"
setlocal enableDelayedExpansion
for %%L in ("!LF!") do set "ln=!ln:%SOH%=%%~L!"
for /f "eol== tokens=1* delims==" %%B in ("!ln!") do (
if "!!"=="" endlocal
set "search=%%C"
if defined search (
setlocal enableDelayedExpansion
>search.txt (echo !search:\=\\!)
endlocal
for %%D in (%~2) do if "%%B"=="%%D" (
findstr /xlg:search.txt "tag_%%B.txt" || >>"tag_%%B.txt" echo %%C
) >nul 2>nul
)
)
)
del search.txt 2>nul
:: Print out the results to the screen
for %%F in (tag_*.txt) do (
echo(
echo %%F:
type %%F
)
答案 1 :(得分:1)
试试这个批处理文件。添加日志文件名作为参数。 e.g:
LISTTAG.BAT SOH.LOG
它将显示所有标记ID及其唯一值。 e.g:
9=387
12=abc
34=asb73
9=123
12=xyz
名为tagNNlist.txt
的文件(其中NN
是标签ID号)将用于查找唯一标签ID和值,但在批次结束时保留为完整的报告。
以下代码中显示的{SOH}
文本实际上是 SOH 字符(ASCII 0x01),因此在您复制&amp;粘贴代码后,应将其更改为 SOH 字符。我必须替换该字符,因为它被服务器剥离了。通过键入0001
,然后按ALT+X
,使用 Wordpad 生成 SOH 字符。副本&amp;使用批处理文件代码将该字符粘贴到记事本中。
需要注意的一点是,代码只会处理从第16列开始的行。示例行中的07:00:32 -SEND:
将被忽略。我假设他们都是从那个固定长度的文本开始的。
的变化:
通过标签ID将生成的标签列表文件更改为单独的文件。例如:tag12list.txt
,tag52list.txt
等
在生成的标记列表文件中删除了标记ID号。例如:12=abc
成为abc
。
LISTTAG.BAT
:
@echo off
setlocal enabledelayedexpansion
if "%~1" == "" (
echo No source file specified.
goto :eof
)
if not exist "%~1" (
echo Source file not found.
goto :eof
)
echo Warning! All "tagNNlist.txt" file in current
echo directory will be deleted and overwritten.
echo Note: The "NN" is tag id number 0-99. e.g.: "tag99list.txt"
pause
echo.
for /l %%a in (0,1,99) do if exist tag%%alist.txt del tag%%alist.txt
for /f "usebackq delims=" %%a in ("%~1") do (
rem *****below two lines strip the first 15 characters (up to "-SEND:")
set x=%%a
set x=!x:~15,99!
rem *****9 tags per line
for /f "tokens=1,2,3,4,5,6,7,8,9 delims={SOH}" %%b in ("!x!") do (
call :dotag "%%b" %*
call :dotag "%%c"
call :dotag "%%d"
call :dotag "%%e"
call :dotag "%%f"
call :dotag "%%g"
call :dotag "%%h"
call :dotag "%%i"
call :dotag "%%j"
)
)
echo.
echo Done.
goto :eof
rem dotag "{id=value}"
:dotag
for /f "tokens=1,2 delims==" %%p in (%1) do (
set z=0
if exist tag%%plist.txt (
call :chktag %%p "%%q"
) else (
rem>tag%%plist.txt
)
if !z! == 0 (
echo %%q>>tag%%plist.txt
echo %~1
)
)
goto :eof
rem chktag {id} "{value}"
:chktag
for /f "delims=" %%y in (tag%1%list.txt) do (
if /i "%%y" == %2 (
set z=1
goto :eof
)
)
goto :eof