1. Computer problem? Tech Support Guy is completely free -- paid for by advertisers and donations. Click here to join today! If you're new to Tech Support Guy, we highly recommend that you visit our Guide for New Members.

Solved: Help with For /r loop

Discussion in 'DOS/Other' started by mcwilsong, Jun 9, 2009.

Thread Status:
Not open for further replies.
  1. mcwilsong

    mcwilsong Thread Starter

    Jun 9, 2009
    I wrote a batch file to make a copy of a file and add "_wgs" to the file name (not the extension). However, I don't know whether the folders (which could number 300 or so and contain 29 or more sub folders each) if there are any existing files already with a "filename_wgs.shp" name. I have to assume that since I haven't run my batch on the folder yet, that the file was created manually and I don't want to overwrite it.
    I would like the command that creates the copy to take into account all *.shp files in the
    loop, but exclude anything that already contains "_wgs.shp" in the file name.

    I tried using the /-Y, but it
    requires a manual reply and I don't want to use /Y because, as I said earlier, I don't want to overwrite the file. This is what I started with:

    for /r %%i in (*.shp) do copy "%%i" "%%~pni_wgs.shp"

    It works great, however, I realized that there are sub directories I want to skip as well. So I figured I'd move copy into xcopy. However, this does not work:

    for /r %%i in (*.shp) do xcopy %%i %%~pni_wgs.shp /t /e /Exclude:excludelist.txt

    excludelist.txt contains:
    left (hoping that it would exclude every folder name that has "left")
    right (hoping that it would exclude every folder name that has "right")
    wgs.shp (hoping that it would exclude every file name that has "wgs.shp")

    All I get is a "Cannot perform a cyclic copy" error. Is what I'm trying to do even possible as the command stands? I'm trying to keep it as simple as possible. Any help would be greatly appreciated!

  2. TheOutcaste


    Aug 7, 2007
    Welcome to TSG!

    When using Xcopy and copying a directory tree, the destination can't be a subfolder of the source. While the For /r loop is returning single file names, the /T and /E switches tell Xcopy that it's copying a tree, so it gives the cyclic copy error.
    You've left off the d modifier, so there is no drive letter specified in the Destination. It will still work, but in some situations, that can give unexpected results, so best to include it: %%~dpnI

    If you remove the /E and /T switches, you'll get another prompt for each file:
    Does C:\Test\filename_wgs.shp specify a file name
    or directory name on the target
    (F = file, D = directory)?

    Xcopy was meant to copy files, not rename them. When copying single files, it expects the Destination to be a folder name ending with \. If you don't have the \, it gives the above prompt. So if you want to rename the file, there is no way to avoid the prompt.

    And neither example will overwrite an existing file. If filename_wgs.shp exists, your code will copy it to filename_wgs_wgs.shp.

    Your best bet is to use a Dir command, pipe it to Findstr to remove the folders you want to exclude, then pipe it to a 2nd Findstr to exclude files that already have the _wgs added to their name

    You then check if filename_wgs.shp already exists, and if not, then copy the file.

    This should do the trick:
    Set _root=C:\Test
    PushD %_root%
    For /F "delims=" %%I In ('Dir /A-D /B /S *.shp^|Findstr /I /V /G:excludelist.txt^|Findstr /E /I /L /V "_wgs.shp"') Do If Not Exist "%%~dpnI_wgs.shp" Copy "%%I" "%%~dpnI_wgs.shp"
    If excludelist.txt is not in the _root folder (C:\Test in this example), you'll need to specify the path to the file.
    To specify a folder name in excludelist.txt, best to use \foldername\ format, or you may get partial matches and exclude folders you didn't intend to.
    For example, if you put folder1 in the excludelist.txt file, it will exclude folder1, folder11, folder1mustbeincluded, and dofolder125now.
    \folder1\ will only exclude folder1.


  3. mcwilsong

    mcwilsong Thread Starter

    Jun 9, 2009
    Excellent! Thank you very much Jerry ... that did work perfectly. One more question ... if I exclude the path part, is there any harm in just running the batch file at the root of the folder structure you want to effect?

    I was just thinking, in terms of ease of use, by copying and pasting the appropriate batch files (in my case: copy_shp.bat, copy_shx.bat, copy_dbf.bat, copy_wgs.bat, excludelist.txt) to the root directory and then running them by calling copy_wgs.bat, someone else using the set of files wouldn't need to alter anything if performing the same function.
  4. TheOutcaste


    Aug 7, 2007
    The Set, PushD and PopD are only needed if the folders you want to work on are not the same as the one the batch file is in, so all you need is the For statement and put the file in the folder you want to work on.
As Seen On
As Seen On...

Welcome to Tech Support Guy!

Are you looking for the solution to your computer problem? Join our site today to ask your question. This site is completely free -- paid for by advertisers and donations.

If you're not already familiar with forums, watch our Welcome Guide to get started.

Join over 733,556 other people just like you!

Thread Status:
Not open for further replies.

Short URL to this thread: https://techguy.org/833910