Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'll explain what's what I'm trying to do.

From a project with thousands of files, we want to remove many of them matching a pattern, but we want to store a backup. We are looking for a method to perform a move opeation that will keep the relative folder structure in the destination.

I mean, if we have:

D:\matchingfile1.txt
D:\matchingfile2.txt
D:\nonmatchingfile1.txt
D:\nonmatchingfile2.txt
D:\foofolder\matchingfile1.txt
D:\foofolder\matchingfile2.txt
D:\foofolder\nonmatchingfile1.txt
D:\foofolder\nonmatchingfile2.txt
D:\barfolder\sub\matchingfile1.txt
D:\barfolder\sub\matchingfile2.txt
D:\barfolder\sub\nonmatchingfile1.txt
D:\barfolder\sub\nonmatchingfile2.txt

We want to move it to D:\_BACKUP\20130527\ with this result:

D:\_BACKUP\20130527\matchingfile1.txt
D:\_BACKUP\20130527\matchingfile2.txt
D:\_BACKUP\20130527\foofolder\matchingfile1.txt
D:\_BACKUP\20130527\foofolder\matchingfile2.txt
D:\_BACKUP\20130527\barfolder\sub\matchingfile1.txt
D:\_BACKUP\20130527\barfolder\sub\matchingfile2.txt

NOTE1: Files to move are not those named "matchingfile", this is just an illustrative example. What we currently extracted is a list of all the full paths of our target files (plain text), so this has to be the input of the method/command/program.

NOTE2: directory level may be any.

Work is under Windows 7 OS.

Lots of thanks in advance.

share|improve this question

5 Answers 5

up vote 2 down vote accepted

I've taken a look at it now when I've gotten home and this is working for me

setlocal EnableDelayedExpansion

IF [%1]==[] (set txtpath=%CD%\list.txt) else (set txtpath=%1)
set projectfolder="D:\"
set savelocation="D:\_Backup"

cd /d %projectfolder%
set lenght=%CD%
set i=-1
set n=0
:nextChar
    set /A i+=1
    set c=!lenght:~%i%,1!
    set /A n+=1
    if "!c!" == "" goto endLine 
    goto nextChar

:endLine
for /f "tokens=*" %%A in (!txtpath!) do call :filecheck "%%A"
goto :eof

:filecheck
set folder=%~pd1%
set location="!folder:~%n%!"
if not exist %savelocation%\%location% mkdir %savelocation%\%location%
copy %1 %savelocation%\%location% && del /q %1
goto :eof
endlocal

Remade the script to reflect that you wanted a *.txt file as input for the filepaths, this works for me, you need to set "projectfolder", "savelocation", "txtpath" but after that the script can be run from anywhere, and does what you want it. (you can drag and drop a txt file on it after you setup the projectfolder/savelocation)

It recreates the folder structure for all the files thats in the .txt file, at any location on the drive (or another drive for that matter), copies the files and then deletes them from their original folder.

share|improve this answer
    
Hi @Curs3d. Well, in the end I wasn't asking somebody to program it for me (I'm developer too and I also love bats), but asking for an existing command/program. Lots of thanks Curs3d. It does the job perfectly. Both your solution and Martin's work perfectly and I don't know which to accept. I'll finally accept yours for not requiring any aditional component to be installed. –  Áxel Costas Pena May 29 '13 at 16:35

Well, this would be a simple xcopy command, but you have the _backup folder on D: so traversing the D: drive would pick up the _backup folder

You could make the _backup hidden so you could

xcopy d:\matchingile?.txt d:\_backup\matchingfile?.txt /s

share|improve this answer
    
Id think of a better way, but Ive been awake way to long –  Keltari May 27 '13 at 9:26
    
How can this help we to keep relative folders on backup folder? Am I missing something? –  Áxel Costas Pena May 27 '13 at 9:33

Personally I've just started learning some powershell scripting, which would do nicely for a job like this. Just save the code in a .ps1 file and make sure you enable the running of powershell scripts (Set-ExecutionPolicy RemoteSigned). This way you have a more powerful filtering tool, using regular expressions, instead of just wildcards. The script could ofcourse also be modified to accept a list of files from a text-file.

# Variables
$backupFolder="D:\_BACKUP\20130527";
$folderTobeBackedUp="D:\";
$overwrite=$True;
$filter="filenameToBeMatched";

function recurseDir($dir)
{
    $dirs=$(get-childitem "$($dir.FullName)");

    foreach( $f in $dirs)
    {
        if( $f.PSisContainer )
        {
            recurseDir $f;
        }    
        elseif($f.Name -imatch "$filter")
        {
            copyFile $f;
        }
    }
}

function copyFile($f)
{
    $newFile=$($f.FullName).Replace($folderTobeBackedUp, $backupFolder);
    $parent="$(Split-Path $newFile -Parent)";
    if( -not (test-path $parent))
    {
        new-item -Path $parent -type "directory";
    }
    try
    {
        $f.CopyTo("$newFile", $overwrite);
        (rmdir -Path $f.FullName -Force);
    }
    catch
    {
        Write-Host $_.Exception.ToString();
    }   
}

$folders=$(get-childitem "$folderTobeBackedUp");
foreach($f in $folders)
{
    if( $f.Name -imatch "_BACKUP" )
    {
        ; # Do nothing.
    }
    elseif( $f.PSisContainer )
    {
        recurseDir $f;
    }
    elseif($f.Name -imatch "$filter")
    {
        copyFile $f;
    }
}
share|improve this answer
    
Hi @Martin. Well, in the end I wasn't asking somebody to program it for me (I'm developer too and I also love bats), but asking for an existing command/program. Lots of thanks Martin. It does the job perfectly. Both your solution and Curs3d work perfectly and I don't know which to accept. I'll finally accept Curs3d's for not requiring any aditional component to be installed, and I sorry so much not accepting yours, because it's also simply perfect. Lots of thanks again. –  Áxel Costas Pena May 29 '13 at 16:36
    
No problem, programmed it for my on sake really, got an exam coming up, which includes PowerShell scripting. If you're running Window Vista or greater, PowerShell is included and don't need to be installed, but if you don't need more functionality later or you don't need regex matching, then Curs3d's solution is probably the easiest to go with. –  Martin May 29 '13 at 17:47

Would it be an option to install unix tools tools or a script language (like perl)?

Essentially if you have any language that can read a file, you can read it line by line into a variable and perform

I'm just sketchig this in perl here (it will sure need some refinement):

while ( <NAMESFILE> ) {  # for all lines until EOF
   $file= $_;
   system("xcopy $file d:\backup\$file");
   system("del $file");
}

The xcopy in this case will create the full path and the del will then remove the original.

share|improve this answer
    
Hmmm... but $file will contain full path! –  Áxel Costas Pena May 29 '13 at 16:33
    
downvote even, huh? I guess it wouldn't be too hard to cut the two first characters here, I said I'd "sketch" an answer, I wasn't even sure if you were willing to use Perl. –  The-Dood Jun 13 '13 at 19:11

XCOPY does the job that you need. It can be used in a batch job thusly:

xcopy "C:\FolderName\*.*" "D:\FolderName\*.*" /D /E /V /C /I /F /H /R /K /Y /Z

Here is the complete syntax, including the meanings of the switches:

C:\>xcopy /?
Copies files and directory trees.

XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]
                           [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/U]
                           [/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z]
                           [/EXCLUDE:file1[+file2][+file3]...]

  source       Specifies the file(s) to copy.
  destination  Specifies the location and/or name of new files.
  /A           Copies only files with the archive attribute set,
               doesn't change the attribute.
  /M           Copies only files with the archive attribute set,
               turns off the archive attribute.
  /D:m-d-y     Copies files changed on or after the specified date.
               If no date is given, copies only those files whose
               source time is newer than the destination time.
  /EXCLUDE:file1[+file2][+file3]...
               Specifies a list of files containing strings.  Each string
               should be in a separate line in the files.  When any of the
               strings match any part of the absolute path of the file to be
               copied, that file will be excluded from being copied.  For
               example, specifying a string like \obj\ or .obj will exclude
               all files underneath the directory obj or all files with the
               .obj extension respectively.
  /P           Prompts you before creating each destination file.
  /S           Copies directories and subdirectories except empty ones.
  /E           Copies directories and subdirectories, including empty ones.
               Same as /S /E. May be used to modify /T.
  /V           Verifies each new file.
  /W           Prompts you to press a key before copying.
  /C           Continues copying even if errors occur.
  /I           If destination does not exist and copying more than one file,
               assumes that destination must be a directory.
  /Q           Does not display file names while copying.
  /F           Displays full source and destination file names while copying.
  /L           Displays files that would be copied.
  /G           Allows the copying of encrypted files to destination that does
               not support encryption.
  /H           Copies hidden and system files also.
  /R           Overwrites read-only files.
  /T           Creates directory structure, but does not copy files. Does not
               include empty directories or subdirectories. /T /E includes
               empty directories and subdirectories.
  /U           Copies only files that already exist in destination.
  /K           Copies attributes. Normal Xcopy will reset read-only attributes.
  /N           Copies using the generated short names.
  /O           Copies file ownership and ACL information.
  /X           Copies file audit settings (implies /O).
  /Y           Suppresses prompting to confirm you want to overwrite an
               existing destination file.
  /-Y          Causes prompting to confirm you want to overwrite an
               existing destination file.
  /Z           Copies networked files in restartable mode.

The switch /Y may be preset in the COPYCMD environment variable.
This may be overridden with /-Y on the command line.
share|improve this answer
    
-1 - this doesn't answer his original requirements of copying files from one drive to another folder on the same drive –  ncdownpat May 27 '13 at 16:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.