Using the FOR command to copy files listed in a text file

A coworker asked me for a script. Here’s the request:

… would want to copy all files on this list [an attached text document] to another location (doesn’t really matter where for now). All are currently located in \\server\share\folder. The path in the new location should begin with the part after “folder”…

In a nutshell, here is the high-level description of what the script must do:

Given a text file which provides a list of files, copy the files from a fixed source to a fixed destination, recreating the directory trees on the destination. A simple file copy won’t work because there may be files in the source folders which should not be copied.

Sample content of the text file is:

client\CD120\Samarai Legends\Drafts\drafts folder.txt
client\CD120\Samarai Legends\Inbox\Legends.doc
client\CD120\Bushido Warriors\Inbox\Warrior Code.doc

The solution to this is to make a simple batch file that parses the content of the text file, generating the appropriate xcopy command to copy the file. We’ll call the batch file xcopylist.bat; its one line of content is below. Change c:\temp\ to whatever path you want the files copied to. (I used c:\temp\ for testing.) Change \\server\share\folder to the root folder of the files to copy.

for /f "delims=" %%i in (filelist.txt) do echo D|xcopy "\\server\share\folder\%%i" "c:\temp\%%i" /i /z /y

Put the file list in the same directory as the batch file and name the file list filelist.txt. Then run the batch file and viola! You’ve got to love the for command, which lets you (among other things) parse text files and use the line-by-line output. Another trick in here is the output parser pipe, which allows us to automatically press the “D” key with each xcopy command.

Note: The batch file overwrites files in the destination automatically. To turn this off (have it prompt you), change /y to /y- in the batch file. However, if you’re using Windows NT 4.0, just delete the /y switch altogether – it’s only supported in Windows XP and Windows 2000.

Popularity: 16% [?]

Related posts:

  1. Moving a FrontPage Web site to a non-FrontPage Web site
  2. Exporting directories to delimited text files
  3. Toggling your HOSTS file
  4. Five simple rules for creating delimited text files
  5. Renaming files in a subdirectory tree

21 comments to Using the FOR command to copy files listed in a text file

  • Happy Guy

    Thanks Brian for this nice solution. It saved a lot of time for us :)

  • Joe

    Hello,

    I would like to implement your script to backup starred picasa photos, these are stored in a file named starlist.txt in the format:

    C:\Users\Joe\Pictures\Play\Journeys\New Years 08\IMG_1682.JPG
    C:\Users\Joe\Pictures\Play\Journeys\New Years 08\IMG_1683.JPG
    etc

    The problem being that your script uses the whole file path when duplicating the files, resulting in the following (unusable) address:

    C:\temp\C:\Users\Joe\Pictures\Play\Journeys\New Years 08\IMG_1682.JPG

    Is there a simple modification that can be made to the script which would remove the “C:\Users\Joe\Pictures” element from the created file path?

    Many thanks in advance for your assistance.

  • The simples thing is to make a copy of starlist.txt, do a search/replace removing all text c:\users\joe\pictures, and running the script against that.

    As far as I can remember (it’s been a while), there is no easy way to truncate or replace data in strings from within the Windows shell.

  • Joe

    Many thanks for your fast response!

    I modified starlist.txt as you suggested, so that each line reads as follows:
    \Play\Journeys\Spain 05\Chris’s Photos\DSCN0319.JPG
    etc

    This duplicated the files successfully, but put each individual image into a folder with the image name, within the correct folder structure e.g:
    D:\Starred Photos\Play\Journeys\Spain 05\Chris’s Photos\DSCN0319.JPG\DSCN0319.JPG

    I am using the following command:
    for /f “delims=” %%i in (starlist.txt) do echo D|xcopy “C:\Users\Joe\Pictures%%i” “D:\Starred Photos\%%i” /i /z /y

    Do you have any suggestions on why the folder is being created?

  • Only thing I can think to try is adding a backslash after the folder “Pictures” in the path “C:\Users\Joe\Pictures%%i” (that is, make it “C:\Users\Joe\Pictures\%%i”

  • Manuel

    Hi Brian, this script is very useful, i apreciate to much if you can help me to modify
    a little this script.
    I´ve a filename.txt file with the names of the files something like these

    text.txt
    text.txt
    text.txt

    etc…

    But the really I need is copy the files with your relative path to another folder

    thanks and regards

    MM

  • Not 100% sure what you need… You mention a relative path — relative to what?

    Something you can do to help explain may be to give an example of one line in the text file, and an example of how the script would use that line. For example, if one line was this:

    test.txt

    … and you wanted to generate this:

    copy test.txt c:\files\test.txt

    … the script would be:

    for /f “delims=” %%i in (filelist.txt) do copy “%%i” “c:\files\%%i”

    Give me an illustrative example and I’ll help if I can.

  • Manuel

    Hi Brian,

    Supose that I got a file “filelist.txt” with this content

    test.txt
    test1.txt
    test2.txt

    ….etc

    but these files (test.txt, test1.txt, etc…) are in a differents folders, something like that

    c:\Temp\test\test.txt
    c:\Temp\test1\test1.txt
    c:\Temp\test2\test2.txt

    I need copy all of the contents in the “Temp” folder, to another folder “Final”, but including the same folder structure of the “Temp” folder, see below

    c:\Final\ \\this folder are empty at first

    This is that i will to result after execute the batch file

    c:\Final\test\test.txt
    c:\Final\test1\test1.txt
    c:\Final\test2\test2.txt

    But I only have the filelist.txt, this file dont have the relative paths of the files

    Ps sorry for my enligish

    Thanks and regards

    MM

  • So it sounds like you want to copy only those files whose names are in the given file list. The easiest way I can think of is by doing this:

    for /f "delims=" %%i in (filelist.txt) do xcopy "c:\Temp\%%i?" "c:\Final" /i /z /y /s

    The two key changes are the question mark at the end of the first path in the xcopy command, and the /s switch.

    By adding a question mark to the end of the first path, you allow xcopy to look for “all files that match the pattern”. Of course, this means that test1.txt and test1.txtt would both match, but since it’s unlikely you have files with more than three characters in the extension, this should be fine.

    The /s switch tells xcopy to search all subdirectories of the source directory for matching files, and copy them to the destination with the same folder hierarchy.

    To test it out, run the following:

    xcopy c:\windows\*.log c:\temp /i /z /y /s

    This will copy every *.log file from the Windows directory to your c:\temp directory. This will result in operations like the following:

    C:\windows\WindowsUpdate.log
    C:\windows\Debug\blastcln.log
    C:\windows\Debug\UserMode\userenv.log
    C:\windows\Logs\DirectX.log
    C:\windows\Microsoft.NET\Framework\v2.0.50727\ngen.log

    In the temp directory, you’d have this:

    C:\temp\WindowsUpdate.log
    C:\temp\Debug\blastcln.log
    C:\temp\Debug\UserMode\userenv.log
    C:\temp\Logs\DirectX.log
    C:\temp\Microsoft.NET\Framework\v2.0.50727\ngen.log

    Viola!

  • Manuel

    Hi Brian, thanks for your help. The script its working ok…I´ve an error in the
    sintaxis of the xcopy command…but now is everything OK

    Regards

  • Manuel

    Hi Brian, a need your help one more time

    Supose that I got a file “filelist.txt” with this content (names without extensions)

    test
    test1
    test2
    test3
    test4

    ….etc

    I have a folder with a lot of files named like this form (test.txt, test.xls, test.doc, etc…) see example below

    c:\Temp\test.txt
    \test.xls
    \test.doc
    \test1.txt
    \test1.xls
    \test1.doc
    .
    .
    .

    etc.

    I need copy all of the contents in the “Temp” folder, to another folder “Final”, with subfolders named like
    the name of files and including the files with same name inside of the several folder see below

    c:\Final\ \\this folder are empty at first or don´t exist at first

    This is that i will to result after execute the batch file

    c:\Final\test\test.txt
    \test.xls
    \test.doc

    c:\Final\test1\test1.txt
    \test1.xls
    \test1.doc

    c:\Final\test2\test2.txt
    \test2.xls
    \test3.doc

    Ps sorry for my enligish, I hope I had explained correctly

    Thanks and regards

    MM

  • Manuel,

    I’d love to help out, but your requests are getting very specialized, and getting close to consulting services. I’ll try to point you in the right direction…

    First, you’re going to need to a combination of a FOR loop to parse the filenames in the text file. Next, you need to create the directory, then copy files to it.

    Try creating a batch file with this:

    for /f "delims=" %%i in (filelist.txt) do (
    md c:\Final\%%i
    xcopy c:\temp\%%i.* c:\Final\%%i /i /z /y /s
    )

    I didn’t test that but it looks right. :)

    If you need further services, you can consider hiring me as a consultant. :D

  • Josh

    I appear to be having the same issue as Joe.

    Before running this in my live environment, I decided to test it first.

    My bat file states:
    for /f “delims=” %%I in (test.txt) do echo D| xcopy “C:\Documents and Settings\e1000721\Desktop\New\%%I” “C:\Copy\%%I”

    My test.txt file states
    Level\test\File1.txt
    Level\test\File2.txt
    test\File3.txt
    test\File4.txt

    And it does copy over fine, only when it finishes, the file structure appears as
    C:\Copy\Level\test\File1.txt\File2.txt
    C:\Copy\Level\test\File2.txt\File2.txt
    C:\Copy\test\File3.txt\File3.txt
    C:\Copy\test\File4.txt\File4.txt

    Any thoughts on how I can get it to not make the last subfolder the name of the file?

    Thanks.

  • Try replacing xcopy with a regular copy command — it might do the trick. (For some reason xcopy is defaulting to behavior assuming that the destination is a directory, not a file. Usually this only happens when the /I switch is present.)

  • Josh

    Tried copy and it just bombed out. I then put a pause at the end of the batch file so I could see exactly what it was doing. The issue with the xcopy wound up being that it was set for Directory instead of File so I changed D| to F| before the xcopy thus making the script:

    for /f “delims=” %%I in (test.txt) do echo F| xcopy “C:\Documents and Settings\e1000721\Desktop\New\%%I” “C:\Copy\%%I”

    Thanks again for the great help.

  • Sari

    Thanks Brian! This was exactly what I was trying to do. Years ago I did a lot with DOS batch files and now I can not remember how to do it since dragging and dropping everything.
    I modified your example a bit to create a text file listing files, which were not found.

  • David Lim

    Brian,

    You are a genius! I have been trying to do this all night without success and am glad that I found this site. Thank you!!!

    Keep up the good work.

    David

  • You’ve saved me sooo much time! “Thank You” can’t begin to explain my gratitude. You’re awesome :)

  • Lester

    Hi,

    How I have a problem, the filelist.txt that i’ve created constains different locations (server locations),
    \\server1\temp1
    \\server2\temp2
    \\server3\temp3
    Can this be done using your batch file?

    thanks,

  • If your filelist.txt has the full path to the files, you need to do two things:

    1. Remove any path prefix to the source parameter of the xcopy command.
    2. Remove the first slash in the UNC path in the destination parameter of the xcopy command.

    Fortunately the command shell in Windows allows you to specify a substring of characters from a variable (called string indexing, see http://www.dostips.com/DtTipsStringManipulation.php). If the variable %i was your full UNC path, and you want to drop the first character (so you don’t have a double-slash in your path), you can specify %i:~1 — the :~1 says “start from the second character” (strings are zero-indexed, so the first character is at position 0, the second at position 1, etc.).

    Your command line can then be:

    for /f “delims=” %%i in (filelist.txt) do ( set fil=%%i
    echo D|xcopy “%%i” “c:\temp\%fil:~1%” /i /z /y )

    You have to set a temporary variable (“fil” in the above), since as far as I can tell string indexing doesn’t work with the %%i for loop variable.

  • PatrickMc

    Nice problem and solution. Can a scripting langugage such as biterscripting make the task easy ? Here is a script.

    # Script CopyFiles.txt
    var str src, dest, list, file
    cat “/path/to/list file.txt” > $list
    lex “1″ $list > $file
    while ($file “”)
    do
    system copy (“\”"+$src+”/”+$file) (“\”"+$dest+”/”+$file)
    lex “1″ $list > $file
    done

    This script is in biterscripting ( http://www.biterscripting.com ). Save the script in file C:/Scripts/CopyFiles.txt. Call the script using the following command.

    script “C:/Scripts/CopyFiles.txt” src(“/path/to/source folder”) dest(“/path/to/destination folder”)

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>