Link to home
Start Free TrialLog in
Avatar of fedexpert
fedexpert

asked on

Batch File to Copy Files based on filenames listed in text file.

I have a folder with 2000 jpg image files and a text file that lists out about 900  filenames  that I need to have copied over to a destination folder.   The text file does not have the path, just the file name.  

It seems simple, but I am unfamiliar with what the batch file syntax does. I've seen solutions that use for /F "delims-"%%a    and other that use for /f %%a......

Please specify whether the solution should be run in cmd.exe vs creating a .bat file.
I just need something that works.

Thanks.
Avatar of effx
effx
Flag of United Kingdom of Great Britain and Northern Ireland image

do you have the option of using VBS?
Avatar of fedexpert
fedexpert

ASKER

No, that is not available to me.
This should get you on your way.

Set your source and destination locations in line 2 and 3 and set the filename of your text file in line 4.
@echo off
set source=c:\source
set destination=c:\destination
set files=%source%\file.txt

for /f "tokens=*" %%a in ("%source%\file.txt") do (
   copy /y "%source%\%%a" "%destination%" >nul
)

Open in new window

Copy the code into Notepad. Edit lines 2, 3 and 4. Save it as a batch file. And you're good to go!

SOLUTION
Avatar of ReneGe
ReneGe
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Avatar of Steve Knight
Steve Knight
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Three at exactly the same time... that must be a record... Billprew / billDL you disappoint me on not making it 5 :-)

Steve
Coool!
Oops... Posted again due to an error:

Set your source and destination locations in line 2 and 3 and set the filename of your text file in line 4.
@echo off
set source=c:\source
set destination=c:\destination
set files=%source%\file.txt

for /f "tokens=*" %%a in ("%files%") do (
   copy /y "%source%\%%a" "%destination%" >nul
)

Open in new window

Copy the code into Notepad. Edit lines 2, 3 and 4. Save it as a batch file. And you're good to go!
Inspired by Paul's script, added /Y to copy
 
@ECHO OFF

SET Source=C:\Source
SET Dest=C:\Destination
SET FileNameList=FileNameList.txt

IF NOT EXIST "%Dest%" MD "%Dest%"

FOR /R "%Source%" %%A IN (*.jpg) DO FINDSTR -i "%%~nxA" "%FileNameList%" && COPY /y "%%~fA" "%Dest%"

PAUSE

Open in new window


If you want to preserve the source path:
 
@ECHO OFF

SET Source=C:\Source
SET Dest=C:\Destination
SET FileNameList=FileNameList.txt

IF NOT EXIST "%Dest%" MD "%Dest%"

FOR /R "%Source%" %%A IN (*.jpg) DO FINDSTR -i "%%~nxA" "%FileNameList%" && (
	IF NOT EXIST "%Dest%%%~pA" MD "%Dest%%%~pA"
	copy /y "%%~fA" "%Dest%%%~pA"
)

PAUSE

Open in new window

@Steve

==> Billprew / billDL you disappoint me on not making it 5 :-)

Sorry dude, the "bills" are paying the "bills"...

~bp
@Paul

Won't you need usebackq ?

~bp
Not too many ways to skin this one, but seems like a single command at a command prompt (not in a BAT file) could do the job:

for /F "usebackq tokens=*" %F in ("c:\filelist.txt") do @copy "c:\fromdir\%~F" "c:\todir"

Open in new window

~bp
Thanks for the quick response all.  @PaultoMasi - I wasn't able to get your code to copy to the destination folder.  I was only able to get dragonit and ReneGe's to work.  

@Dragonit @ ReneGe - thanks for your assistance.  

Is there a way to have it rename the files as well or should that be a separate script? Thought?
How would you want them renamed?

~bp
Well, for some reason the file has 2-3 extraneous characters at the end.

So, I would only want the first 6 characters.

So for 12345678.jpg, I would rename to 123456.jpg
Yes.

The following will add _Backup to the file name.

@ECHO OFF

SET Source=C:\Source
SET Dest=C:\Destination
SET FileNameList=FileNameList.txt

IF NOT EXIST "%Dest%" MD "%Dest%"

FOR /R "%Source%" %%A IN (*.jpg) DO FINDSTR -i "%%~nxA" "%FileNameList%" && (
	IF NOT EXIST "%Dest%%%~pA" MD "%Dest%%%~pA"
	copy /y "%%~fA" "%Dest%%%~pA%%~nA_Backup%%~xA"
)

PAUSE

Open in new window

@fedexpert:
I posted my new script before you answered to Bill
This should handle renaming to just the first 6 characters.  It doesn't account for duplicates, not sure what you would want to do with those?

@echo off
setlocal EnableDelayedExpansion
set BaseDir=c:\fromdir
set DestDir=c:\todir
set ListFile=c:\temp\filelist.txt
for /F "usebackq tokens=*" %%F in ("%ListFile%") do (
  set Name=%%~nF
  copy "%BaseDir%\%%~F" "%DestDir%\!Name:0,6!.%%~xF"
)

Open in new window

~bp
Here you go

@ECHO OFF
SETLOCAL EnableDelayedExpansion

SET Source=C:\Source
SET Dest=C:\Destination
SET FileNameList=FileNameList.txt

IF NOT EXIST "%Dest%" MD "%Dest%"

FOR /R "%Source%" %%A IN (*.jpg) DO FINDSTR -i "%%~nxA" "%FileNameList%" && (
	IF NOT EXIST "%Dest%%%~pA" MD "%Dest%%%~pA"
	SET FileName=%%~nA
	SET FileName=!FileName:~0,6!
	copy /y "%%~fA" "%Dest%%%~pA!FileName!%%~xA"
)

PAUSE

Open in new window

If you do not wish to keep path at destination,

Change line 14 from:
copy /y "%%~fA" "%Dest%%%~pA!FileName!%%~xA"
TO:
copy /y "%%~fA" "%Dest%\!FileName!%%~xA"
Rene's post brings up an interesting question, my posts have assumed the filenames in the TXT file include the extension, is that true?

~bp
In the question, it is stated JPG files. So I assume extension is not an issue.

However, in 37041214, poster confirmed script to be working. Therefore, the extension must be in the file list, text file.

Cheers,
Rene
Correct, the .jpg is within the text file.
Okay, my approach should be okay then.

~bp
Thank you bill. I stand to be corrected. USEBACKQ is required when using double quotes around the filespec...

@echo off
set source=c:\source
set destination=c:\destination
set files=%source%\file.txt

for /f "tokens=* usebackq" %%a in ("%files%") do (
   copy /y "%source%\%%a" "%destination%" >nul
)

Open in new window


It just gets better and better...
Ah! Just read the renaming thing... to do with 6 characters blah, blah, blah...
I'm sure this works fine....

Don't forget to edit lines 4, 5 and 6 to point to your own files/locations.
@echo off
setlocal enabledelayedexpansion

set source=c:\source
set destination=c:\destination
set files=%source%\file.txt

for /f "tokens=* usebackq" %%a in ("%files%") do (
   set filename=%%~na
   copy /y "%source%\!filename!%%~xa" "%destination%" >nul
)

Open in new window

Oops! Pressed ENTER accidentally.... This is what you need!

@echo off
setlocal enabledelayedexpansion

set source=c:\source
set destination=c:\destination
set files=%source%\file.txt

for /f "tokens=* usebackq" %%a in ("%files%") do (
   set filename=%%~na
   copy /y "%source%\!filename:~0,6!%%~xa" "%destination%" >nul
)
ReneGe...

Testing for, and creating the destination folder is a nice touch (I like seeing validation).

Also, testing for the existence of the textfile such as:

   if not exist "%source%\filelist.txt" (
      echo Error msg !!
      exit /b
   )


Good points Paul!
Blimey away for a bit sorting out stuff for tomorrow and thought it was in the bag (maybe divided by three) and all hell breaks loose!
@Steve: Sounds like you are having fun :)
blowing up baloons, banners, chucking toys in piles....
Lucky you!!
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@ReneGe - Okay, this might be user error, but only one file is getting copied with the filename !FileName!.jpg.   Also, I made the suggested change to line 14 (RE: ID: 37041348
)   Is there something causing it to slow down because it took a REALLY long time to copy the one file?  
Its odd because @dragon-it code snippet copied the files relatively quickly considering the number of files.

@PaultoMasi/@BillPrew - still not able to get the file to run.

I have posted the code snippets in the attachment.

Thanks All, I am really appreciating your efforts
@ReneGe - 
@ECHO OFF

SET Source=E:\Cornerstone\Dallas
SET Dest=E:\Cornerstone\Upload
SET FileNameList=Files.txt

IF NOT EXIST "%Dest%" MD "%Dest%"
FOR /R "%Source%" %%A IN (*.jpg) DO FINDSTR -i "%%~nxA" "%FileNameList%" && (
	IF NOT EXIST "%Dest%%%~pA" MD "%Dest%%%~pA"
	SET FileName=%%~nA
	SET FileName=!FileName:~0,6!
	copy /y "%%~fA" "%Dest%\!FileName!%%~xA"
)

PAUSE
_________________________________________________________

@BillPrew
@echo off
setlocal EnableDelayedExpansion
set BaseDir=e:\cornerstone\dallas
set DestDir=e:\cornerstone\upload
set ListFile=e:\cornerstone\dallas\files.txt
for /F "usebackq tokens=*" %%F in ("%ListFile%") do (
  set Name=%%~nF
  copy "%BaseDir%\%%~F" "%DestDir%\!Name:0,6!.%%~xF"
)

Open in new window

@fedexpert
You specified "The text file does not have the path, just the file name. "

Is it ok to assume that your files have a path other than the root dir of the source folder, and could also be in sub-direcrories?
I have a folder called Cornerstone. WIthin this folder, I have an Upload folder which is the destination folder for the photos....and I have a Dallas folder where the folders are stored.

The files.txt  lists the photos as


12345678.jpg
87654321.jpg

and so on.   Does that make sense?  Or did I make it worse?
*** I meant to say a Dallas folder where the photos are stored.  Sorry.
bp... Dear, dear, dear... It's happening to you too...

A couple of errors (http:#37041306) in your line:

   copy "%BaseDir%\%%~F" "%DestDir%\!Name:0,6!.%%~xF"

which should read:

   copy "%BaseDir%\%%~F" "%DestDir%\!Name:~0,6!%%~xF"

Appears you missed a tilde (~) character (it happens to the best of us) and added one period (.) too many!


Also, I don't think there's a difference between:

   copy "%BaseDir%\%%~F"

and:

   copy "%BaseDir%\%%F"

in the current context.

Otherwise, you're good to go!
In your code snippet above you have cut out the

"SETLOCAL EnableDelayedExpansion"

from reneGe's script which is why I imagine it is copying all the files over the top of the same file (which is why it seems slow for one file)

Steve
@paultoMasi,  I just saw your last post.  Perfect. Thanks so much!

@dragonit, Renege - I also have a separate need for you posts as well, so points awarded. Thanks.

Thanks to all!  I truly appreciate your effort.
OK my offering then is:

@echo off
SETLOCAL EnableDelayedExpansion
set base=c:\cornerstone
cd /d "%base%"
for /f "delims=" %%a in ('type %base%\files.txt') do (
  set name=%%~na
  xcopy /D "%base%\dallas\!name:~0,6!%%~xa" "%base%\upload"
)

Steve
Posting late here (having spent time setting up a mock environment etc...)

Just tested this and it works 100% !!


@echo off
setlocal enabledelayedexpansion

set files=e:\Cornerstone\Dallas\files.txt
set source=e:\Cornerstone\Dallas
set destination=e:\Cornerstone\Upload

for /f "tokens=* usebackq" %%a in ("%files%") do (
   set filename=%%~na
   copy /y "%source%\%%a" "%destination%\!filename:~0,6!%%~xa" >nul
)
Oops! Didn't realise the question is already closed!...

Wish I had tested sooner...

Would have saved a lot of time in the long run!

Thanks a bunch for accepting my solution...

Thank you all - it was a joint effort!
That one was fun!
Very cool collaboration.

Thanks for the points!

Cheers,
Rene