/ / Esegue il ciclo del file CSV con batch - problema di interruzione di riga - Windows, file batch, cmd

Passa attraverso il file CSV con batch - problema di interruzione di riga - windows, batch-file, cmd

Questa è l'estensione a un'altra domanda (Ripeti il ​​file CSV con batch - Problema di spazio)

Ho il contenuto del file CSV come questo

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

Sto ripetendo questo file usando questo comando.

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

Ma poiché c'è un'interruzione di riga nella seconda riga, ottengo 3 record anche se ci sono due record nel file.

Come risolvere questo problema? Grazie in anticipo.

risposte:

2 per risposta № 1

Il problema principale sembra essere quello di contare le virgolette in una riga.
Se il conteggio delle virgolette è dispari, è necessario aggiungere la riga successiva e contare di nuovo le virgolette.

Il conteggio dei caratteri in una stringa è un po 'complicato, se non riesci a scorrere tutti i caratteri.
Ho usato qui la tecnica di riduzione ritardata, ogni citazione sarà efficacemente sostituita da a +1 e tutti gli altri personaggi vengono rimossi.
Per iniziare e terminare la linea in modo corretto c'è sempre un extra +1 all'inizio, che sarà compensato da a -1 di fronte.

Il trucco principale è sostituire il testo completo da una citazione all'altra con esattamente una +1 sostituendo ogni citazione con !!#:#=.
Funziona come !#:#=...<some text>...! sarà sempre esteso a +1, come contenuto della variabile # è +1 e così il modello di ricerca # non può essere trovato
Le altre sostituzioni sono necessarie solo per evitare problemi con punti esclamativi e accenti circolari nel testo.

:::::::::::::::::::::::::::::::::::::::::::
: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
)

E la logica per aggiungere righe e inserire avanzamenti riga

@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
)

1 per risposta № 2

Il file Batch di seguito fa quello che vuoi:

@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

Ho aggiunto i requisiti che hai richiesto nel tuo fileargomento precedente, ovvero il sesso può essere vuoto (ed è cambiato dal carattere @ come ho spiegato nella mia risposta a quell'argomento) e il nome può includere virgole. Ho testato il programma con questo file di dati:

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

E ottieni questi risultati:

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,

Notare che qualsiasi campo che contiene virgole o spazi deve essere racchiuso tra virgolette.