1

これは別の質問への拡張です (バッチで CSV ファイルをループする - スペースの問題)

私はこのようなcsvファイルの内容を持っています

name,sex,age,description,date
venu,m,16,test mesg,2012-05-01
test,f,22,"He is good guy
and
brilliant",2012-05-01

このコマンドを使用してこのファイルをループしています。

For /F "usebackq tokens=1-3 delims=" %%x in (test.csv) Do (

しかし、2 行目に改行があるため、ファイルに 2 つのレコードがあるにもかかわらず、3 つのレコードを取得しています。

これを修正する方法は?前もって感謝します。

4

2 に答える 2

2

主な問題は、行内の引用符を数えることです。
引用符の数が奇数の場合は、次の行を追加して、引用符を再度カウントする必要があります。

すべての文字を繰り返し処理しない場合、文字列内の文字のカウントは少し難しいです。
ここでは遅延削減テクニックを使用しました。各引用符は効果的に a に置き換えられ、+1他のすべての文字は削除されます。
適切な方法で行を開始および終了するために、先頭に常に 1 つの余分なものがあり、これはin front+1によって補われます。-1

主なトリックは、ある引用から次の引用への完全なテキストを、+1各引用を!!#:#=.
これは、変数の内容が であり、検索パターンが見つからないため、!#:#=...<some text>...!常に に展開されるように機能します。 他の置換は、テキスト内の感嘆符とキャレットの問題を回避するためにのみ必要です。 +1#+1#

:::::::::::::::::::::::::::::::::::::::::::
:CountQuotes <stringVar> <result>
setlocal EnableDelayedExpansion
set "line=!%~1!"
set "#=+1"

rem DelayedExpansion: double all quotes
set "line=!line:"=""!"

rem DelayedExpansion: remove all carets ^
set "line=!line:^=!"

rem PercentExpansion: Remove all !
set "line=%line:!=%"

rem PercentExpansion: Replace double quotes to !!#:#=
set "line=-1^!#:#=%line:""=^!^!#:#=%"

for /F "delims=" %%X in ("!line!") do (
    set /a count=%%X!
)

(
    endlocal
    set %~2=%count%
    exit /b
)

そして、行を追加して改行を挿入するためのロジック

@echo off
setlocal DisableDelayedExpansion
set "lastLine="
set LF=^


rem Two empty lines
for /F "delims=" %%A in (test.csv) do (
    set "line=%%A"
    setlocal EnableDelayedExpansion
    set "line=!line:\=\x!"
    if defined lastLine (
        set "line=!lastLine!\n!line!"
    )

    call :CountQuotes line quoteCnt
    set /a rest=quoteCnt %% 2
    if !rest! == 0 (
        for %%L in ("!LF!") DO set "line=!line:\n=%%~L!"
        set "line=!line:\\=\!"
        echo Complete Row: !Line!
        echo(
        set "lastLine="
    ) ELSE (
        set "lastLine=!line!"
    )

    for /F "delims=" %%X in (""!lastLine!"") DO (
        endlocal
        set "lastLine=%%~X"
    )
)
exit /b

:::::::::::::::::::::::::::::::::::::::::::
:CountQuotes <stringVar> <result>
setlocal EnableDelayedExpansion
set "line=!%~1!"
set "#=+1"

rem DelayedExpansion: double all quotes
set "line=!line:"=""!"

rem DelayedExpansion: remove all carets ^
set "line=!line:^=!"

rem PercentExpansion: Remove all !
set "line=%line:!=%"

rem PercentExpansion: Replace double quotes to !!#:#=
set "line=-1^!#:#=%line:""=^!^!#:#=%"

for /F "delims=" %%X in ("!line!") do (
    set /a count=%%X!
)

(
    endlocal
    set %~2=%count%
    exit /b
)
于 2012-06-05T11:35:27.847 に答える
1

以下のバッチファイルは、あなたが望むことをします:

@echo Off
setlocal EnableDelayedExpansion

call :processFile < test.csv
goto :EOF


:processFile
   set line=
   set /P line=
   if not defined line exit /b
   set "line=!line:,,=,@,!"
   for %%a in (name sex age description mydate) do set %%a=
   for %%a in (!line!) do (
      if not defined name (
         set "name=%%a"
      ) else if not defined sex (
         set "sex=%%a"
      ) else if not defined age (
         set "age=%%a"
      ) else if not defined description (
         set "description=%%a"
      ) else if not defined mydate (
         set "mydate=%%a"
      )
   )
   :checkDate
   if defined mydate goto show
      set /P line=
      for /F "tokens=1* delims=," %%a in ("!line!") do (
         set "description=!description! %%a"
         set "mydate=%%b"
      )
   goto checkDate
   :show
   for %%a in (name sex age description mydate) do set /P "=%%a=!%%a!, " < NUL
   echo/
goto processFile

前のトピックで要求された要件を追加しました。つまり、性別は空である可能性があり (そのトピックへの回答で説明したように @ 文字で変更されます)、名前にはコンマが含まれる可能性があります。このデータ ファイルを使用してプログラムをテストしました。

name,sex,age,description,date
venu,m,16,"test mesg",2012-05-01
test,,22,"He is good guy
and
brilliant",2012-05-01
"venu,gopal",m,16,"Another
multi-line
description",2012-05-02

これらの結果を取得します。

name=name, sex=sex, age=age, description=description, mydate=date,
name=venu, sex=m, age=16, description="test mesg", mydate=2012-05-01,
name=test, sex=@, age=22, description="He is good guy and brilliant", mydate=2012-05-01,
name="venu,gopal", sex=m, age=16, description="Another multi-line description", mydate=2012-05-02,

カンマまたはスペースを含むフィールドは引用符で囲む必要があることに注意してください。

于 2012-05-24T03:01:16.033 に答える