Reading empty values in "for" command in a windows batch file
I have a question with the "for" batch command in windows.
I have a file called keys.txt which contains this line..
key,value,x86,windows7
I want to parse this line and开发者_运维知识库 store the 4 comma seperated variables in 4 variables. I accomplish that by the following windows batch script.
for /F "tokens=1,2,3,4* delims=," %%i
in (keys.txt) do (
echo first is %%i
echo second is %%j
echo third is %%k
echo fourth is %%l
echo rest is %%m
echo -------------
)
However, when i modify the keys.txt to
key,value,,windows7
The third variable is printed as windows7. I would expect the 3rd variable to be empty and the 4th variable to be windows7. If i give a space between the 2 comma's like this
key,value, ,windows7
Then it prints the 3rd variable as empty and the 4th variable as Windows7.
Anyone knows how i can make the earlier case (i.e the one without the space) also to work correctly?
Try this. Idea fom here
The script preprocess each line assigning the text #NUL# to each empty slot. You can disregard #NUL# values after that.
cls
setlocal enabledelayedexpansion
@echo off
for /f "tokens=*" %%X in (keys.txt) do (
set "work=%%X"
:: fill empty fields with "#NUL#" ...
:: but do it twice, just in case consecutive fields are empty
for /l %%i in (1,1,2) do set "work=!work:,,=,#NUL#,!"
for /F "tokens=1,2,3,4* delims=," %%i in ("!work!") do (
echo first is %%i
echo second is %%j
echo third is %%k
echo fourth is %%l
echo rest is %%m
echo -------------
))
HTH
for
is designed to not preserve null/empty tokens on some systems, so allocates next next token to the placeholder (as long as it's also not null/empty). This also happens when printing text with leading space or blank lines on some versions of Windows™.
To work around this, preprocess the data and fill some value in empty data eg. space (as you've experimented) to preserve all tokens.
for /f "delims=" %a in (test.1) do set data=%a& set data=!data:,=","!& for /f "tokens=1-4 delims=," %i in ("!data!") do set a=%i-%j-%k-%l& echo !a:"=!
The above code preprocesses data similar to CSV format, which also works with data containing spaces within same 'cell'.
eg. output: key-value--windows 7
If your data contains the delimiter ,
and you want it preserved as part of data, then change the delimiter in the for
or escape it during preprocessing.
Update (a practical application for mass processing):
With this method you can also autofill (common)data eg. if you're processing multiple files and file names are to be read from a template file, then instead of typing file names on command prompt for every file to be processed, you can create a template file and read file names from it.
If most of them have a common extension eg. .txt
, then just type ,,
(blank data) instead of typing .txt everytime, like so:
file1,,
file 2,,
file 3la,,
different file,.pdf
Then in your code, the blank spaces ,,
will be prefilled with .txt
(saving time creating the template file).
Here's the code for preprocessing file names before being fed to main process code:
for /f "delims=" %a in (test.1) do set data=%a& set data=!data:,=","!& for /f "tokens=1,2 delims=," %i in ("!data!") do (
REM replace empty cells with ".txt"
echo %j | find "." >nul && (set j=%j) || set j=.txt
set data=%i!j! & echo !data:"=!
)
精彩评论