batch file reading in badly formed filename and needs to quote it

LuckyLucks
LuckyLucks used Ask the Experts™
on
Hi,

 I was working with the following code to read in the source filepath (including filename), destination file name, destination subfolder and destination parent folder.

My batch_input.csv provides these input parameters. However, the data in the destination filename is not very clean and can not be fixed much. It contains special characters as well as spaces.

Z:\process\abc1.pdf      American Spa Message & feet Co. Inc._HBA-11556a_0_20131101_20131115_Major Renovation Document Filed.doc      American Spa Message & feet Co. Inc.      A
Z:\process\abc1.pdf      My Tech Ltd_VDS-715ada61_0_20021021_20140301_Statement of Work.doc      My Tech Ltd      I


On a command line, if I executed > copy /Y C:/123.pdf C:/Test/"American Spa Message & feet Co. Inc."
it creates the subfolder correctly.
If I executed > copy /Y C:/123.pdf C:/Test/"American Spa Message & feet Co. Inc."/"American Spa Message & feet Co. Inc._HBA-11556a_0_20131101_20131115_Major Renovation Document Filed.doc" it copies the file into it with the name correctly.

Now, i am trying to automate this in batch as follows, but its not working correctly.
set echo on
FOR /F "tokens=* delims=" %%x in (batch_input.csv) DO call :doit %%x
exit

:doit
if not exist C:\Test mkdir C:\Test
if not exist C:\Test\%4 mkdir C:\Test\%4
if not exist C:\Test\%4\"%3" mkdir C:\Test\%4\"%3"
copy /Y %1 C:\Test\%4\"%3"\"%2"
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Bill PrewIT / Software Engineering Consultant
Top Expert 2016

Commented:
It's going to be pretty hard to parse that correctly as it stands.  Could you change the way it is produced to be like this, and then delimit by commas?

Z:\process\abc1.pdf,American Spa Message & feet Co. Inc._HBA-11556a_0_20131101_20131115_Major Renovation Document Filed.doc,American Spa Message & feet Co. Inc.,A
Z:\process\abc1.pdf,My Tech Ltd_VDS-715ada61_0_20021021_20140301_Statement of Work.doc,My Tech Ltd,I

Open in new window

If not, then will there allways be the same number of spaces (greater than 1) between each field in the file?  If so we might be able to trigger off this.

~bp

Author

Commented:
I have tried getting comma delimited files but columns # 2 and 3 that contain special characters are always double quote qualified in the output.

Yes, there is always a single space between the columns.
Bill PrewIT / Software Engineering Consultant
Top Expert 2016

Commented:
Well, if there is always a single space between columns, and also there can be single spaces in the middle of the actual fields, then it's near impossible to know where a field begins and ends.  

You mention double quotes though now at this point, which your test data did not show.  Could you please post up a real example of what the data file will look like, taken from a real data file.  There may be patterns in the data we can trigger off of to parse it if it is quoting fields, etc.

~bp
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Bill PrewIT / Software Engineering Consultant
Top Expert 2016

Commented:
And if you really do have lines that have the fields that contain spaces surrounded by double quotes, and a space between each field, like this:

Z:\process\abc1.pdf "American Spa Message & feet Co. Inc._HBA-11556a_0_20131101_20131115_Major Renovation Document Filed.doc" "American Spa Message & feet Co. Inc." A
Z:\process\abc1.pdf "My Tech Ltd_VDS-715ada61_0_20021021_20140301_Statement of Work.doc" "My Tech Ltd" I

Open in new window

Then this should get the job done:

@echo off

REM Define locations of files and folders
set ControlFile=control.txt
set BaseDir=C:\Test

REM Read each line of the control file, pass it to a subroutin for processing
for /f "usebackq tokens=*" %%A in ("%ControlFile%") do (
  call :DoIt %%A
)

REM Leave the script now
exit /b

REM Subroutine to break up the control line, and then copy the file as specified
:DoIt
  if not exist "%BaseDir%\" mkdir "%BaseDir%"
  if not exist "%BaseDir%\%4\" mkdir "%BaseDir%\%4"
  if not exist "%BaseDir%\%4\%3\" mkdir "%BaseDir%\%4\%3"
  copy /Y "%1" "%BaseDir%\%4\%3\%2" 
  exit /b

Open in new window

Also, you shouldn't need the first two MKDIR lines in the subroutine, but I left them in for now.  MKDIR is nice in that it will create all parent folders needed to create the lowest level directory, so you don't have to do those separately.

~bp

Author

Commented:
Just a tweak, is it possible to allow for a comma delimitor? Cant seem to get i working...
FYI-I had to let go of the space between columns since its a txt now, not a csv.

So, input would look like: controlfile.txt

"Z:\process\abc1.pdf","American Spa Message & feet Co. Inc._HBA-11556a_0_20131101_20131115_Major Renovation Document Filed.doc","American Spa Message & feet Co. Inc.","A"
"Z:\process\abc1.pdf","My Tech Ltd_VDS-715ada61_0_20021021_20140301_Statement of Work.doc","My Tech Ltd","I"

for /f "usebackq tokens=* delims=," %%A in ("%ControlFile%") do (
                                           
I have changed the code slightly as

Author

Commented:
for /f "usebackq tokens=* delims=," %%A in ("%ControlFile%") do (
                                           
I have changed the code slightly as above.
IT / Software Engineering Consultant
Top Expert 2016
Commented:
This should handle that format of the control file now:

@echo off

REM Define locations of files and folders
set ControlFile=control2.txt
set BaseDir=C:\Test

REM Read each line of the control file, pass it to a subroutin for processing
for /f "usebackq tokens=1-4 delims=," %%A in ("%ControlFile%") do (
  call :DoIt %%A %%B %%C %%D
)

REM Leave the script now
exit /b

REM Subroutine to break up the control line, and then copy the file as specified
:DoIt
  if not exist "%BaseDir%\" mkdir "%BaseDir%"
  if not exist "%BaseDir%\%~4\" mkdir "%BaseDir%\%~4"
  if not exist "%BaseDir%\%~4\%~3\" mkdir "%BaseDir%\%~4\%~3"
  copy /Y "%1" "%BaseDir%\%~4\%~3\%~2" 
  exit /b

Open in new window

~bp

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial