I am trying to backup critical folders and their contents on a daily basis so that, should my data drive fail, I have a backup of the important project files but my working data drive is much larger than my backup drive (19:6) so I would like to restrict the backup to just the important files:
RoboCopy %Source% %Dest% *.* /s /xo /purgeworks; the /xo is to speed up the backup by skipping over files not modified (necessary as it would take more than a day to backup 4+ TB of data) and /purge ensures the backup drive doesn't have copies of files I no longer need.
The problem is that there are files in folders named QA that I never want to keep backups of, so specifying /xd QA should skip over these files... but the naming isn't consistent, sometimes it's QA, other times QA_v2 (or 3 or 4) other examples include dates like QA_20160708. I have searched posts like this one that seem to say it's possible to use a wildcard but all combinations of:
RoboCopy %Source% %Dest% *.* /s /xo /purge /xd "*QA*"
RoboCopy %Source% %Dest% *.* /s /xo /purge /xd *QA*
RoboCopy %Source% %Dest% *.* /s /xo /purge /xf "*QA*"
RoboCopy %Source% %Dest% *.* /s /xo /purge /xf *QA*
RoboCopy %Source% %Dest% *.* /s /xo /purge /xd QA
RoboCopy %Source% %Dest% *.* /s /xo /purge /xf QAstill copy a folder called QA_v2 in %Source%.
Is there a reliable way to skip folders and subfolders of folders that contain a string with wildcards? It might be important (or not) that I am using a batch file as a scheduled task.
I could do this with a python script using os.walk but shutil.copyfile is really slow compared to RoboCopy so this would be an absolute last resort.
3 Answers
I'm sorry, but according to the documentation at :
/xf <FileName>[ ...] Excludes files that match the specified names or paths. Note that FileName can include wildcard characters (* and ?).
/xd <Directory>[ ...] Excludes directories that match the specified names and paths.
So this specifically means that wildcard can be used in the /xf flag but not in the /xd flag.
1You can see the following links and try it may be one work for you as PETER suggested that /xd don't accept wildcards as per documentations it sounds like that but I think nothing is impossible every problem have a solution
U can try it with GUI mode if robocopy GUI or any new version of robocopy or RICH COPY tool alterative command or tool I will try to search it for you more
(v=msdn.10)?redirectedfrom=MSDN
Meanwhile u see the following discussions and advive links for robocopy and try some of them if any work for you
Using robocopy and excluding multiple directories
1hope any of link tools references work for you if any worked do tell me in comment which one worked for you if not feel free to ask further queries and if worked then don't forget to vote the answer and accept the answer
Like in the comment above, i wrote a python script. But instead of reinvent the wheel (even if i don't doubt result is very good too), it just generates a .bat file with robocopy commands.
Very easy and uses the power of robocopy
Here is the script (so short that it doesn't need classes but i usually use this structure for more complex one). The example here is to save sources without all vendor code or .git history (just an example) I can generate several commands by adding "dirs" dict int the Prm section
import os
class Prm: out_file = "Robocop.bat" exclude_defaults = ['.git', 'vendor', 'cache', 'node_modules', 'var', '.idea'] dirs = [ {'src': 'G:\\Develop', 'dest': 'F:\\G_2021-08\\Develop', 'exclude': exclude_defaults} ] cmd = 'robocopy {} {} /E /R:5 /W:3 /XO /XD {} > {}\n'
class RoboGen: def gen(self): with open(Prm.out_file, 'w') as of: for root_dir in Prm.dirs: exclude_dirs = [] log_fname = "{}.log".format(root_dir['src'].replace(':','').replace('\\','_')) for root, dirs, files in os.walk(root_dir['src']): for xclude in root_dir['exclude']: if xclude in dirs: exclude_dirs.append(os.path.join(root, xclude)) dirs.remove(xclude) #of.write("{}\n".format(root)) cmd = Prm.cmd.format(root_dir['src'], root_dir['dest'], '"{}"'.format('" "'.join(exclude_dirs)), log_fname) of.write('{}\n'.format(cmd))
if __name__ == "__main__": RoboGen().gen()