Reputation: 21
I need to create a script to read a csv file with the ';' char as field delimiter. I use a FOR /F loop like this:
@echo off
FOR /F "skip=1 tokens=1-7 delims=;" %%a in (file.csv) do (
echo Ref: %%~a
echo Gru: %%~b
echo Sin: %%~c
echo St: %%~d
echo Ma: %%~e
echo Or: %%~f
echo Es: %%~g
echo ----------------------
)
And the file has this structure:
A123;00;B123;0;0;;0;
A124;00;B124;5;0;20010984;0;
Some fields are empty, how can i store into 7 variables the content of each corresponding field?
Upvotes: 0
Views: 1324
Reputation: 34949
The for /F
loop collapses multiple adjacent delimiters into a single one. But you can work around that when you put the line string in between ""
and replace every delimiter ;
by ";"
, which leads to a string where each delimited item is enclosed in ""
, even blank ones, so adjacent ;
become separated. Afterwards, the quotation marks can easily be removed by using the ~
-modifier for the for
meta-variable:
rem // Read file and loop through all (non-empty) lines:
for /F skip^=1^ usebackq^ delims^=^ eol^= %%L in ("file.csv") do (
rem // Store current line string:
set "LINE=%%L"
rem // Toggle delayed expansion:
setlocal EnableDelayedExpansion
rem /* Surround whole line string in `""` and replace each `;` by `";"`, leading to
rem each item appearing in between `""`; the outer-most pair of quotes is needed
rem to tell `for /F` that its set is a literal string: */
for /F "tokens=1-7 delims=;" %%a in (""!LINE:^;=";"!"") do (
endlocal
rem // Use the `~`-modifier to remove the surrounding quotes from each item:
echo Ref: %%~a
echo Gru: %%~b
echo Sin: %%~c
echo St: %%~d
echo Ma: %%~e
echo Or: %%~f
echo Es: %%~g
echo ----------------------
)
)
This will fail in case any field in the input data contains ;
on its own (in which case the field must be quoted).
Upvotes: 3
Reputation: 30153
You could accomplish the task easy using PowerShell
:
powershell -noprofile -command "& {Import-Csv -Delimiter ';' -Path file.csv}"
If you insist upon batch-file then there exists a (non-trivial) solution:
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
FOR /F "eol=' skip=1 delims=" %%G in (file.csv) do (
set "_line=%%~G"
REM add a backslash (or other character) in front of every semicolon
call set "_line=%%_line:;=\;%%"
FOR /F "tokens=1-7 delims=;" %%a in ('call echo "%%_line%%"') do (
call :callecho Ref: "%%~a"
call :callecho Gru: "%%~b"
call :callecho Sin: "%%~c"
call :callecho St: "%%~d"
call :callecho Ma: "%%~e"
call :callecho Or: "%%~f"
call :callecho Es: "%%~g"
echo ----------------------
)
)
ENDLOCAL
goto :eof
:callecho
set "_item=%~2"
REM display everything except the last character (=added space)
set "_item=%_item:~0,-1%"
SETLOCAL EnableDelayedExpansion
echo(%~1 !_item!
ENDLOCAL
goto :eof
Result: D:\bat\SO\61748659.bat
Ref: A&123 Gru: 00 Sin: B123 St: 0 Ma: 0 Or: Es: g0 ---------------------- Ref: A124 Gru: Sin: B&124 St: 5 Ma: 0 Or: 20010984 Es: g0 ----------------------
Using the following sample file: type file.csv
Ref;Gru;Sin;St;Ma;Or;Es;
A&123;00;B123;0;0;;g0;
A124;;B&124;5;0;20010984;g0;
Upvotes: 0