Link to home
Start Free TrialLog in
Avatar of Ralph Gould
Ralph GouldFlag for United States of America

asked on

win7 batch file using For /R function

I receive a text file with a list of file names, 1 name per line, file name only, no path, that the requester wants a copy of. These files will be selected and copied from a huge library of files which have sub-folders. This is currently done manually and takes an enormous amount of time. I want to search for the files from the list through all sub-folders and copy them to a separate folder.

I can use the For /R function for all files or selected extensions but do not see how to drive it from a text file of file names.
SOLUTION
Avatar of Robert Schutt
Robert Schutt
Flag of Netherlands 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
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
Avatar of Ralph Gould

ASKER

dragon-it:
nice thought but program that produces the file list has no clue about paths on another system. tks

Robert
Haven't tried it yet but thought I needed /R to walk thru the master directory and its associated sub directories?
Yes, I used C:\temp but you should put your master directory there. Likewise change list.txt to the name of the file containing the filename you need to find.
Sorry what I meant was:

Program to make index... or you could have it do this once at the beginning of each search... that means it scans the files once rather than for each one to find:

@echo off
(for /r "c:\startdir" %%a in (*.*) do echo "%%~nxa","%%~dpa")> "%temp%\index.txt"

Then to search that:

@echo off
(for /r "c:\startdir" %%a in (*.*) do echo %%~nxa^|%%~dpa)> "%temp%\index.txt"
echo The list of files is now in "%temp%\index.txt"

echo Now you can use findstr to look for all the files in "find.txt" in the index.txt file and report back their paths:

for /f "tokens=1,2 delims=^|" %%a in ('findstr /i /b /l /g:find.txt ^< "%temp%\index.txt"') do (
  echo Filename is %%~a, path is %%~b
  echo So use in your copy "%%~b%%~a"
)
When a file that matches the name in the file list I need to copy it to a single folder named c:\File_Dest and I don't need the file list displayed. can u help.
tks
You could be right that it's faster (certainly when the list doesn't have to be refreshed for each search). The for loops in my example could be switched around of course to have a similar effect but still runs through the directories every time.
if you look at the line
echo ** %%b

Open in new window

that should be easy to convert to a copy?
Robert:

When a file that matches the name in the file list I need to copy it to a single folder named c:\File_Dest and I don't need the file list displayed( echo). can u help.
tks
Robert
I get the file_list.txt file echoed, nothing copies.
here's what the batch file looks like:

@echo on
set File_Source=c:\File_Source
set File_Dest=c:\File_Dest
set file_list=c:\File_List\file_list.txt

if not exist "%File_Dest%" mkdir "%File_Dest%"

for /f "tokens=1 delims=" %%a in ('c:\File_List\file_list.txt') do (
 echo * %%a
 FOR /R c:\File_Source %%b IN (%%a) DO Copy "%%b" c:\File_Dest\
)

Perhaps needs another set of () for 2nd DO?
The file list is printed to the screen with the other echo (you can take that out but I used it as a sort of progress indicator). You took out the "if exist" so maybe that caused a problem? I get the files copied ok with this code:
for /f "tokens=1 delims=" %%a in ('type list.txt') do (
 FOR /R c:\temp %%b IN (%%a) DO if exist "%%b" Copy "%%b" C:\Temp2\
)

Open in new window

The destination folder needs to exist and of course you need read access to the source files.
OK then this should do your copy if you want to do it the way I suggested.... depends how many files to search etc.

Either this all is one:

@echo off
(for /r "c:\file_source" %%a in (*.*) do echo %%~nxa^|%%~dpa)> "%temp%\index.txt"
echo The list of files is now in "%temp%\index.txt"

for /f "tokens=1,2 delims=^|" %%a in ('findstr /i /b /l /g:find.txt ^< "%temp%\index.txt"') do (
  echo Filename %%~a is in path %%~b
  copy /y "%%~b%%~a" "c:\File_Dest\"
) 

Open in new window


Or make index:

@echo off
(for /r "c:\file_source" %%a in (*.*) do echo %%~nxa^|%%~dpa)> "%temp%\index.txt"
echo The list of files is now in "%temp%\index.txt"

Open in new window


Search it for files in find.txt
@echo off
for /f "tokens=1,2 delims=^|" %%a in ('findstr /i /b /l /g:find.txt ^< "%temp%\index.txt"') do (
  echo Filename is %%~a, path is %%~b
  copy /y "%%~b%%~a" "c:\File_Dest\"
) 

Open in new window

Ah, found another problem, you took out "type" when replacing the list filename. I also used the variables you prepared:
@echo on
set File_Source=c:\File_Source\
set File_Dest=c:\File_Dest\
set file_list=c:\File_List\file_list.txt

if not exist "%File_Dest%" mkdir "%File_Dest%"

for /f "tokens=1 delims=" %%a in ('type "%file_list%"') do (
 FOR /R "%File_Source%" %%b IN (%%a) DO (
  If Exist "%%b" Copy "%%b" "%File_Dest%"
 )
)

Open in new window

Robert
looks better, walks thru all directories but only copies the first item in the file list to the dest directory (I have 4 entries in the file list file as follows)
ENUtxt.pdf (this one gets copied)
Getting Started.pdf
BRUChangelog.pdf
W9 Form.pdf
Have you tried changing the order of the files in the list to see if it's always the first one that succeeds? Could be a lot of reasons why the files are not found, first of all could be they don't exist. ;-)
Did you try mine?  Amended to your paths.... only fiddling while getting kids in bed....

@echo on
set File_Source=c:\File_Source\
set File_Dest=c:\File_Dest\
set file_list=c:\File_List\file_list.txt

if not exist "%File_Dest%" mkdir "%File_Dest%"

echo Making index
(for /r "%File_Source%" %%a in (*.*) do echo %%~nxa^|%%~dpa)> "%temp%\index.txt"
echo The list of files is now in "%temp%\index.txt"

echo Searching for the files
for /f "tokens=1,2 delims=^|" %%a in ('findstr /i /b /l /g:%file_list% ^< "%temp%\index.txt"') do (
  echo Filename %%~a is in path %%~b
  copy /y "%%~b%%~a" "%File_Dest%"
) 

Open in new window

Robert
it seems to find the appropriate files but only copies the one, regardless of where I put it in the list. It is however, the only file that does not have any spaces in the name..
I found a problem with spaces in the filenames. Haven't found a solution yet... Seems dragon's script may not have that problem?
Yep, that's it, although in your list there was another file without spaces (BRUChangelog.pdf) so there may be another problem.
Robert
that's it, only copies files that do not have spaces in the name!
I tried a few others
Robert
no the BRU.. doc is a planned error (doesn't exist)

Dragon
haven't tried yours yet, will shortly

BTW thanks for all the help folks!!!
Yep, I'm afraid I can't get it to work, the only other version I have works only if the folders don't have any spaces in them...
Sorry to hear that, I thought that using quotes around file name solved that problem. Maybe double quotes will do it.

Anyway Dragons works just fine, so I can use that one.

Thank you all!!!
You could adjust the order to reverse it and run down all the dirs instead of files, then check in each dir for each of the files:

@echo off
set File_Source=c:\users\stephen
set File_Dest=c:\File_Dest\
set file_list=find.txt

if not exist "%File_Dest%" mkdir "%File_Dest%"

REM Run down all dirs under start dir using DIR command
REM For each of those check for all the files in file list.
cd /d "%File_Source%"
for /f "delims=" %%D in ('dir /b /s /ad') do (
  for /f "delims=" %%F in (%file_list%) do if exist "%%~D\%%~F" Copy /Y "%%~D\%%~F" "%File_Dest%"
)

Open in new window


No idea whether that is faster or slower than caching a list of all files, probably depends if the list is 5 or 200.
No problem, was something to do while waiting for boys to go to sleep...
You're absolutely right dragon, guess I got stuck with the For /R that I should've let go.