Solved

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

Posted on 2014-02-25
7
307 Views
Last Modified: 2014-02-26
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"
0
Comment
Question by:LuckyLucks
  • 4
  • 3
7 Comments
 
LVL 52

Expert Comment

by:Bill Prew
ID: 39887631
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
0
 

Author Comment

by:LuckyLucks
ID: 39887906
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.
0
 
LVL 52

Expert Comment

by:Bill Prew
ID: 39888482
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
0
Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

 
LVL 52

Expert Comment

by:Bill Prew
ID: 39888555
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
0
 

Author Comment

by:LuckyLucks
ID: 39889161
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
0
 

Author Comment

by:LuckyLucks
ID: 39889163
for /f "usebackq tokens=* delims=," %%A in ("%ControlFile%") do (
                                           
I have changed the code slightly as above.
0
 
LVL 52

Accepted Solution

by:
Bill Prew earned 500 total points
ID: 39889281
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
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
Slowly Changing Dimension Transformation component in data task flow is very useful for us to manage and control how data changes in SSIS.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now