Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
I'm having problems parsing comma separated values.
My file is a dump from a small database, and looks like this:
<number>,<name>,<street>,<city>,<email>,<phone>
Example:
12,"Person A",,,a@email.com,
134,"Person B","Some street",,b@email.com,
34,"Person C","Some street","Some city",c@email.com,My for structure is:
for /f "tokens=1,2,5 delims=," %%i in (myfile.txt) do (
@echo %%k
)The result is:
ECHO is off.
ECHO is off.
c@email.comOnly the last one behaves as I expect it to.
So the for structure does not parse empty fields.
Can anybody help?

Hi
This help, I've created a file just to test it. Ive allowered for 8 fields.@echo off
rem ===========================
rem Read A Comma Delimited List
rem ===========================echo 12,"Person A",,,a@email.com, >Tmp1.txt
echo 134,"Person B","Some street",,b@email.com, >> Tmp1.txt
echo 34,"Person C","Some street","Some city",c@email.com, >> Tmp1.txtrem Initialise Count And Read File
set Count=0
for /f "tokens=1-8 delims=," %%a in ('type tmp1.txt') do call :SetVar %%a %%b %%c %%d %%e %%f %%grem Display Variables
set Item
exit /brem Process Delimited List
:SetVar %1 %2 %3 %4 %5 %6 %7 %8
set /a Count+=1
if (%1)==() exit /b
rem Add Leading Zero If Count < 10
if %Count% LSS 10 (set Item0%Count%=%1
) else (set Item%Count%=%1)
shift
goto SetVar

Thanks, but your script does the same - ignore empty tokens.
I want to be able to pick tokens 1, 2 and 5 from every line, even if tokens 3 and 4 are empty or have something in them.

i know somehow eventually you can do everything in batch, but in terms of productivity and time spent on coding, things can be done in other ways much faster. here's an alternative, if you can afford to install Windows for Unix services (SFU). its done in awk
[code]
awk 'BEGIN{FS=","}
{print $1,$2,$5}
' "file"
[/code]
output:
12 "Person A" a@email.com
134 "Person B" b@email.com
34 "Person C" c@email.com

I agree with ghostdog.
Here's a perl version
====================================
C:\>perl -F, -lane "print join ' ', @F[0,1,4]" myfile.txt

cool, another option for OP, this time Python
[code]
for line in open("file"):
... line =line.split(",")
... print line[0],line[1],line[4]
[/code]and another in SFU
[code]
cut -d"," -f1,2,5 file
[/code]

Clearly, perl, awk and others have much more horsepower.
You could 'pad' the csv:
::== padcsv.bat
:: puts EMPTY between pairs of commas, then parses for needed fields@echo off > new.csv
setLocal EnableDelayedExpansionfor /f "tokens=* delims= " %%a in (myfile.txt) do (
set str=%%a
set str=!str:,,=,EMPTY,!
set str=!str:,,=,EMPTY,!
>> new.csv echo !str!
)
for /f "tokens=1,2,5 delims=," %%i in (new.csv) do (
@echo %%k
)
::==
=====================================
If at first you don't succeed, you're about average.M2

Since we're all so egar to offer the solution in a language not requested, here's Window's native script, VBS:
With CreateObject("Scripting.FileSystemObject")
Set Fin = .OpenTextFile("myfile.txt")
Set Fout = .OpenTextFile("out.txt", 2, True)
End With
Do Until Fin.AtEndOfStream
Fout.WriteLine Split(Fin.ReadLine, ",")(4)
Loop
'You other scripters have it so easy, with your StdOut. I could use it, too, but I have no guarantee it'll be available. Technically, I have no guarantee that file manipulation will be available, but I don't think anyone will be running my scripts from IE.

Hi
Try this
Change "EMPTY" for a Space(s), if you want to.
I've re-numbererd the FieldNum variables each time.
Don't ask me how it works! Please
My brain worn out already.
@echo off
SetLocal EnableDelayedExpansion
cls
rem Crate Test File
echo 12,"Person A",,,a@email.com, >Tmp1.txt
echo 134,"Person B","Some street",,b@email.com, >> Tmp1.txt
echo 34,"Person C",,,"Some street","Some city",c@email.com, >> Tmp1.txt
for /f "tokens=*" %%a in ('type tmp1.txt') do (
call :DelFields
set Data=%%a
call :SetVar !Data!
)
exit /b:DelFields
for /L %%a in (1,1,10) do set Field%%a=
exit /b
:SetVar %*
set Num=0
set Data=%*
set Data=!Data:,=~!
echo.
echo !Data!
for /L %%a in (0,1,80) do (
set Char=!Data:~%%a,1!
if not "!Char!"=="" (
if "!Char!"=="~" (
set /a Num+=1
if "!Str!"=="" (
set Field!Num!=EMPTY
) else (
set Field!Num!=!Str!
)
set Str=
) else (
set Str=!Str!!Char!
)
set Flag=!Char!
)
)
set /a Num+=1
if "!Flag!"=="~" (
set Field!Num!=EMPTY
) else (
set Field!Num!=!Str!
)
set Field
pause > nul

Holy cow, bat boy!
I won't ask.
=====================================
If at first you don't succeed, you're about average.M2

Thanks guys! You've been most helpful.
I think I'll have to learn perl or something...
I've used Mechanix2Go suggestion to pad the csv-file for this little project.
/Mogens

![]() |
BatchFiles: label syntax?
|
Batch file input for loge...
|

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |