0

非常に大きなFIXメッセージログファイルを使用しています。各メッセージは、SOH文字で区切られたタグのセットを表します。

MQメッセージとは異なり、個々のFIXタグ(およびメッセージ全体)は、固定の長さまたは位置を備えていません。ログには、さまざまなタイプのメッセージが含まれる場合があります(タグの数と順序が異なります)。

サンプル(多くの種類のメッセージの1つ):

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 .. ..

出力の形式は実際には重要ではありません。

提案や推奨事項をいただければ幸いです。

よろしく、ビクターO。

4

2 に答える 2

2

オプション1

以下のバッチスクリプトは、まともなパフォーマンスを発揮します。以下の制限があります

  • 重複をチェックするときは大文字と小文字を区別しません。
  • 値に含まれるすべての値が適切に保持されない場合が=あります

編集-私の元のコードは=値をまったくサポートしていませんでした。変数名にSOH文字を追加することでその制限を緩和し、値の解析に使用されるデリムを変更しました。=これで、の前に一意の値が区別される限り、値に含めることができます=。その後、値が異なる場合、=1つの値のみが保持されます。

上部近くのSOH変数の定義を必ず修正してください。

ログファイルの名前は1番目のパラメーターとして渡され、要求されたタグのリストは2番目のパラメーター(引用符で囲まれています)として渡されます。

@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

このスクリプトにはほとんど制限がありませんが、かなり遅くなります。私が見ることができる唯一の制限は、値を最初から許可しないことです=(先頭=は破棄されます)。

FINDSTR / G:オプションで使用する一時的な「search.txt」ファイルを作成します。FINDSTRの制限により、コマンドライン検索文字列の代わりにファイルを使用します。コマンドライン検索文字列は、10進数の128を超える多くの文字と一致することはできません。また、リテラルの円記号のエスケープ規則がコマンドラインで一貫していません。WindowsFINDSTRコマンドの文書化されていない機能と制限は何ですか?を参照してください。詳細については。

SOH定義を再度修正する必要があり、1番目と2番目の引数は1番目のスクリプトと同じです。

@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
)
于 2012-07-22T04:17:50.583 に答える
1

このバッチファイルを試してください。ログファイル名をパラメータとして追加します。例えば:

LISTTAG.BAT SOH.LOG

すべてのタグIDと一意の値が表示されます。例えば:

9=387
12=abc
34=asb73
9=123
12=xyz

tagNNlist.txt(タグID番号は)という名前のファイルNNは、一意のタグIDと値を見つけるために作成されますが、バッチが終了したときにレポートとしてそのまま残されます。

以下の{SOH}コードに示されているテキストは実際にはSOH文字(ASCII 0x01)であるため、コードをコピーして貼り付けた後、 SOH文字に変更する必要があります。サーバーによって削除されるため、その文字を置き換える必要があります。ワードパッドを使用して、入力してSOH文字を生成し、0001を押しALT+Xます。その文字をコピーして、バッチファイルコードとともにメモ帳に貼り付けます。

注意すべき点の1つは、コードは列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
于 2012-07-20T18:50:04.993 に答える