@ECHO Off
SETLOCAL
rem The following settings for the directories and filenames are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q79571846.txt"
SET "outfile=%destdir%\outfile.txt"
SET /a target_field=9
(
FOR /f "usebackqdelims=" %%e IN ("%filename1%") DO (
SET "line=%%e"
CALL :process
)
)>"%outfile%"
GOTO :EOF
:process
SET "newline="
SET /a field=1
SET "quoted_field="
:buildnew
:: first character
SET "test=%line:~0,1%"
SET "test=%test:"=%"
IF NOT DEFINED test GOTO rabbits_ears
IF NOT "%test%"=="," GOTO transfer_char
:: a comma - count if it's not a quoted field
IF NOT DEFINED quoted_field SET /a field+=1
:transfer_char
SET "newline=%newline%%line:~0,1%"
SET "line=%line:~1%"
IF DEFINED line GOTO buildnew
ECHO %newline%
GOTO :eof
:rabbits_ears
IF DEFINED quoted_field (SET "quoted_field=") ELSE SET "quoted_field=Y"
:: if quoted_field is set, we are within a quoted field, so comma is no longer special
IF %field%==%target_field% SET "newline=%newline%\"
GOTO transfer_char
GOTO :eof
Always verify against a test directory before applying to real data.
Note that if the filename does not contain separators like spaces, then both usebackq and the quotes around %filename1% can be omitted.
YYou would need to change the values assigned to sourcedir and destdir to suit your circumstances. The listing uses a setting that suits my system.
I deliberately include spaces in names to ensure that the spaces are processed correctly.
I used a file named q79571846.txt containing this data for my testing.
14579865,YUPO,"RAMANMAN",2222222,1111,"RAM","Active",,,False
14579865,YUPO,"RAMANMAN",2222222,1111,"RAM","Active",,"Fixme",False
14579865,YUPO,"RAMANMAN",2222222,1111,"RAM","Active",,"Fixme, but I have a comma",False
14579865,YUPO,"RAMANMAN",2222222,1111,"RAM","Active",,Leaveme,False
Result:
14579865,YUPO,"RAMANMAN",2222222,1111,"RAM","Active",,,False
14579865,YUPO,"RAMANMAN",2222222,1111,"RAM","Active",,\"Fixme\",False
14579865,YUPO,"RAMANMAN",2222222,1111,"RAM","Active",,\"Fixme, but I have a comma\",False
14579865,YUPO,"RAMANMAN",2222222,1111,"RAM","Active",,Leaveme,False
Produces the file defined as %outfile%
I operated on field 9, not 23.
Assign each line in turn to line via %%e.
Process each character in line in turn to newline
If the character is ", then frob the quoted_string switch. If the field being processed is the target field, inject the required backslash.
If the character is a comma, then we are moving to the next field number unless we are in a quoted string.
Naturally, this will not process certain characters like % correctly, as some symbols have special meaning to the batch language.
"around the field value string and that one more"must be used to escape the character"inside a field value enclosed in". A replacement of""by\"makes the CSV file invalid for all applications capable of correct parsing a valid CSV file."containing,or"escaped with one more"or newline characters inside such a field value.