MSDOS command(s) to copy files matching pattern in directory structure to local directory - command-line

I have a job that periodically runs and archives files into a folder structure that looks like this:
ArchiveFolder
TimestampFolder
JobnameFolder
job<timestamp>.xml
For a given job, I'd like to collect all xml files in the archive folder into a flat directory (no subdirectories, just all the files) without having to drill down into each one, examine for the proper job, then copy the file.
It seems there should be a fairly straigtforward way of doing this. Any suggestions?
EDIT: I guess I wasn't clear here. The TimeStampFolder will have a name of something like 2011-07-24, the JobnameFolder will have a name like FooFeed or BarFeed, and the job file will have a name like job2011-07-24.xml. There are hundreds to thousands of TimeStampFolders, and each one may have one or more job folders in it. Given a specific job name, I want to collect all the files in all the directories that match that job type, and dump them into the local folder, with no subdirectories.

EDIT1:
SET JOB=JobName
SET OF=OutputFolder
START /wait NET USE Z: "\\ServerName\Sharename\ArchiveFolder" password password_here /USER:domainname\username /P:NO
PUSHD Z:\
FOR /F "USEBACKQ tokens=*" %%A IN (`DIR /b /a:d /s ^| FIND /I "%JOB%"`) DO (
FOR /R %%F IN (%%A) DO (
COPY /Y "%%~fF" "%OF%"
)
)
POPD
It basically locates each subdirectory of ArchiveFolder that includes the JobName in it, then digs into each one that it finds to copy the files out of them.
EDIT2:
Added NET USE to access your network share to perform tasks on the files. If your local machine already has the UNC assigned to a driveletter, you can remove the NET USE command line and change Z: to the assigned driveletter.

#ECHO OFF
FOR /R %%v IN (job*.xml) DO COPY "%%v" c:\out\

Related

Batch File to copy files to new directory while renaming, skipping existing files, and without confirmation

I am creating a batch file to be run later which will be used to copy files from one location to another while renaming the files, skipping any existing files, and without prompting the user. Examples of files to be copied:
00021001.txt
00021001.xyz
00021001.abc
00021001001.jpg
Copied files will have the names:
00022001.txt
00022001.xyz
00022001.abc
00022001001.jpg
Things I have tried:
xcopy C:\Testing\1000012\21\00021*.* C:\Testing\1000013\22\00022*.* /D
This almost does it. It copies all the files starting with "00021" in the first location into the second location while properly renaming them to start with "00022". It skips all the files with the same name and date stamp, but ends up prompting to copy any files from the source which are newer than the target.
robocopy C:\Testing\1000012\21\ C:\Testing\1000013\22\ 00021*.* /xo /xn /xc
I was hoping that by excluding older, newer, and same date files it would work (even if it doesn't rename - I would just do that in a separate step.) Unfortunately, this just ends up overwriting newer source files over existing target files if they are a different filesize.
I have even tried the Copy-Item command in PowerShell. But it doesn't do the renaming like Xcopy, and it doesn't skip existing files (although I can get it to confirm and say "No to All".)
Copy-Item -Path "C:\CWUImageCompare\Testing\1000012\CWU\chemistry\129\21\00021*.*" -Destination "C:\CWUImageCompare\Testing\1000013\CWU\chemistry\129\20\" -Confirm
If xcopy had the "Skip if existing" flag I'd be all set, but it doesn't.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory & destination directory are names
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
FOR /f "skip=1delims=" %%b IN ('xcopy /L /Y "%sourcedir%\00021*.*" "%destdir%\00022*.*" ^|sort') DO (
SET "oname=%%~nxb"
IF EXIST "%destdir%\00022!oname:~5!" (ECHO "%%b" skipped) ELSE (ECHO COPY /y "%%b" "%destdir%\00022!oname:~5!")
)
GOTO :EOF
Always verify against a test directory before applying to real data.
Seems a little complicated, but essentially, execute the xcopy (I omitted the /D for testing) with /L /Y to simply produce a list.
Since the list has a last line that begins with a numeric, whereas the other lines start with a drive-letter, sort the list and skip the first line.
This would implement the date-requirement.
Then grab the part after the first 5 characters of the name+extension, test whether the new name exists and either report or copy as appropriate (The copy command is disarmed for testing)

How to take output of dir search and modify specified file

I'm trying to use this script to assist technicians with renaming files that are found on an end users computer within their %appdata% folder. The script works up until this point, but I can't figure out how to take the output of the DIR search to use it as the current directory so I can modify the destination folder.
Basically, I need to make changes to this folder:
C:\users\bob\appdata\local\apps\2.0\'7'\'7'\time...exe_bfe88f94fc69adaa_0005.0011_none_b883acbb6e8d0075
The two 7's or wildcards are always different folder directory names, so that's why I can't use a static path to make changes to these folders. Anyways, here is the script so far, it works just fine in locating the folder I need, but I cannot seem to use the output to specify it as the target so I can make changes to it. Thank you for your help.
cd %appdata%
cd ..
cd local\apps\2.0
dir "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec" /ad /s
I've tried using the pipeline argument (|) and the '&' and then using a rename command or a removedir, but it cannot find the file specified.
Thank you for your help!
Here's a batch-file which is a little more direct than just recursing the entire tree. It only steps over the two 'unknown' directory names, (%%~nxG\%%~nxH), and checks there for the named directory, (which you should edit as needed on line 3):
#Echo Off & SetLocal EnableExtensions
Set "DirName=time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"
Set "BaseDir=%LocalAppData%\apps\2.0"
Set "AppPath="
For /D %%G In ("%BaseDir%\*")Do For /D %%H In ("%%G\*")Do For %%I In (
"%%H\%DirName%")Do If "%%~aI" GEq "d" Set "AppPath=%%~I"
If Not Defined AppPath Echo %DirName% Not Found & Pause & Exit /B 1
Echo %%AppPath%% = %AppPath% & Pause
Nothing else should be modified except for the last line which I added just to provide some output, (you/your technicians would use "%AppPath%" to reference the target directory from that point forward).
If you were looking for something in powershell, then perhaps this will push you in the right direction:
$DirName = "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"
$AppPath = (RvPa "$Env:LocalAppData\apps\2.0\*\*\$DirName").Path
$AppPath
Once again the last line is just to provide output and show you the variable you'll need to reference your target directory, and the first line will need editing as needed.
This code uses a FOR loop to find directory names that match. There is an ECHO inside the loop since I do not know if multiple directories could be found.
#ECHO OFF
CD "%APPDATA%\.."
FOR /F "delims=" %%A IN ('DIR /S /B /A:D "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"') DO (
ECHO Found directory "%%~A"
SET THEDIR=%%~A
)
DIR "%THEDIR%"
REN "%THEDIR%\file1.txt" "file2.txt"

Copying files from similar multiple folders into each of their child folders

I would like to use a batch file to copy files in a folder to a backup folder (OLD) within, on a Windows server. And I want to do this for multiple folders.
So for example, I have multiple folders, named like this:
C:\A01
C:\A02
C:\A03
...
C:\A50
I will nickname them here as A##.
Each folder has hundreds of files.
Then each year before updating them, I copy those files into a backup folder called OLD, for each A##, so I have a backup of last year's files. Then I copy in new files into C:\A##, in another manual process, individually.
So there will be folders like:
C:\A01\OLD
C:\A02\OLD
C:\A03\OLD
...
C:\A50\OLD
When I do the copy, to the OLD folder, I keep the most recent version of each file. But then the files that I later manually copy in will overwrite in the C:\A## folder and be this year's files, while C:\A##\OLD will contain last year's files.
How can I script this so it will copy all the files for each C:\A## folder into their respective \OLD folder?
I assume I would use a variable for the path I want to copy from and to.
I could use Robocopy or Xcopy.
in a script file
#echo off
cd c:\
for /f "usebackq delims=:" %%a IN (`dir /AD /B ^| FINDSTR /I /R "A[0-9]*"`) DO (
#mkdir "%%a\OLD"
xcopy "%%a\*.*" "%%a\OLD\" /ECIFHRY /D
)
it copy only the updated files (/D) to the OLD subfolder.
if you want to mantain ACLs of the files, use /ECIFHRKOXY
I suggest you to test it in a test folder, that you can generate with this commands directly in the shell
#mkdir c:\test76
cd c:\test76
For /L %a IN (1,1,10) DO #mkdir A%a && echo "the quick brown fox jumps over the lazy dog">A%a\file.txt

How to Copy files that are in a directory to another directory recursively in Windows?

I have to create an script to copy files from a folder structure to other.
My source folder structure is similar to this:
-RootFolder
--ParentFolder1
--SubParentFolder1
--ToCopy
/*Here are the files to copy*/
--SubParentFolder2
--ParentFolder2
--OtherSubParentFolder
--ToCopy
/*Here are the files to copy*/
--ParentFolder3
--OtherSubParentFolder2
I want to copy the files that are in the "ToCopy" folders, into another folder, with this structure:
Destination folder structure:
--TargetDirectory
--SubParentFolder1
//Here the files that were in the ToCopy folder inside the SubParentsFolder1
--OtherSubParentFolder
//Here the files that were in the ToCopy folder inside the OtherSubParentFolder
Notice that I use the name of the "ToCopy" parent folder in the destination subfolders.
I know how I would do this with code (like C#), but I am at a lost on how to achieve it with a Batch file. Is it even possible? Or I would need to use something like powershell?
How can I copy my files following the structure I described?
I think, this should work...
$Folder= gci -path "d:\pstest" -recurse -Filter "ToCopy" | where { $_.psiscontainer }
Foreach ($Foldername in $Folder) {
$Destinationfolder=$Foldername.Parent
copy-item $Foldername.fullname -Destination "d:\Outputfolder\$Destinationfolder" -recurse
}
Hi to follow is a script I hacked away (via help from stack overflow), that reads the files from a txt document, then requests destination folder input and also src folder name it then just goes and recursively copies all the files to the new folder without keeping the old subfolder structure.
I will update this in future with the link to the person that I got the base template from for the admin area, but to keep in mind once you click that Batch can run as though it was a php script then everything makes sense. Took me whole day to research every command and alternative on SS64.com
Major thing to note is the pushd "%~dp0" this I use to make sure batch always uses my current directory as root.
As said I will do a proper write up on this and further stream lining since I am using it actively for moving files during a woocommerce shop update. P.S. the text file name should be entered without the .txt extention and every file name should start on a new line. Also if the destination directory does not exist it will create it. Use excel maybe to list the names then for renaming could output to new column and compile the batch rename command copy to new batch run first batch to fetch files and second batch to rename to preferred title, I do it in steps to keep my sanity.
Sorry was just a example of how I use it, but yes go ahead and enjoy hope this works for you.
#echo off
CLS
setlocal EnableDelayedExpansion
REM Changes root path to relative of current bat folder
pushd "%~dp0"
REM finds files in provided .txt file and copies them to destination directory
REM CHECK FOR ADMIN RIGHTS
COPY /b/y NUL %WINDIR%\06CF2EB6-94E6-4a60-91D8-AB945AE8CF38 >NUL 2>&1
IF ERRORLEVEL 1 GOTO:NONADMIN
DEL %WINDIR%\06CF2EB6-94E6-4a60-91D8-AB945AE8CF38 >NUL 2>&1
:ADMIN
REM GOT ADMIN RIGHTS
COLOR 1F
ECHO Hi, %USERNAME%!
ECHO Please wait...
set /p DEST_DIR="Copy files to:"%=%
set /p SEARCH_DIR="Copy files from:"%=%
#echo.
#echo Please check folder name for accuracy.
#echo Copy files to: %DEST_DIR%
#echo Copy files from: %SEARCH_DIR%
set /p CORRECT_FOLDERS="Are these correct? (please check spelling) y/n:"
if '%CORRECT_FOLDERS%'=='y' GOTO:YES_ANSWER
if '%CORRECT_FOLDERS%'=='n' GOTO:NO_ANSWER
COLOR 2F
ECHO.
PAUSE
GOTO:EOF
:NONADMIN
REM NO ADMIN RIGHTS
COLOR 4F
ECHO.
ECHO PLEASE RUN AS ADMINISTRATOR
ECHO.
pause
GOTO:EOF
:YES_ANSWER
#echo.
#echo you answered yes
#echo.
if exist %DEST_DIR% GOTO:READ_DATA
if not exist %DEST_DIR% md %DEST_DIR%&GOTO:READ_DATA
PAUSE
:NO_ANSWER
#echo.
#echo you answered no
set /p TRY_AGAIN="Try again? y/n:"
if '%TRY_AGAIN%'=='y' GOTO:YES_ANSWER
if '%TRY_AGAIN%'=='n' GOTO:EXIT_PROGRAM
PAUSE
:EXIT_PROGRAM
#echo.
#echo "So Sorry"
PAUSE
GOTO:EOF
:READ_DATA
#echo.
set /p GET_FILENAMES="What is the name of the text file your filenames are stored in?"%=%
if exist %GET_FILENAMES%.txt #echo We will now read and copy the files for you, have some coffee might take awhile & GOTO:WRITE_DATA
if not exist %GET_FILENAMES%.txt #echo Filename does not match, please type only the name without .txt extention & GOTO:READ_DATA
PAUSE
:WRITE_DATA
#echo.
#echo reading file name...
for /f "usebackq delims=" %%a in ("%GET_FILENAMES%.txt") do (
for /r "%SEARCH_DIR%" %%b in ("%%a*") do (
#echo Copy Started...
copy "%%b" "%DEST_DIR%\%%~nxb"
)
)
#echo Copy finished, please review actions. Lekker Man.
PAUSE``

Having XCopy copy a file and not overwrite the previous one if it exists (without prompting)

I'm sending commands to a remote computer in order to have it copy a file.
I want the file to be copied, but not to overwrite the previous file with the same name (if it exists).
I also need the command to run without any prompts (xcopy likes to prompt whether the target name I've specified is file or directory, and it will also prompt about overwriting a file).
I have good results with xcopy /d.
It will copy NEWER files, and since we can assume that existing files have same time-stamp, you will copy only files that don't exist.
just in case anyone else finds this:
robocopy x:\sourcefolder Y:\destfolder /s /e /r:0 /z
much better than xcopy, even gives you a table at the end informing of any failed or skipped files. Doesn't prompt to not overwrite.
Well, there's a certain remedy! It has helped me with saving much of my effort and time on Win10 while writing a setup for our product demo.
Just try to use piping:
#ECHO N|COPY /-Y SourceFiles Destination
As an example I used this piece of code so that I would have a clean gentle quiet and safe copy!
#FOR /D %%F in ("FooPath") DO #(
#ECHO N|COPY /-Y ^"%%~npdxF\*.*^" ^"GooPath^" 3>NUL 2>NUL >NUL
)
where obviously FooPath is the source and GooPath is the destination.
Enjoy!
(main source: https://ss64.com/nt/copy.html)
Following command copy files and folder but not override file if already exist.
xcopy "*.*" "C:\test\" /s /y /d
No way to make it NOT overwrite as far as I know. but /Y will make it overwrite. and /I will get rid of the file/dict prompt. See xcopy /? for all options
You can also use the replace command. It has two modes: to add files that don't exist there or replace files that do exist. You want the previous mode:
replace <path1> <path2> /A
I had to copy AND rename files, so I got the prompt about creating a file or a directory.
This is the, rather "hackish" way I did it:
ECHO F | XCOPY /D "C:\install\dummy\dummy.pdf" "C:\Archive\fffc810e-f01a-47e8-a000-5903fc56f0ec.pdf"
XCOPY will use the "F" to indicate it should create the target as a file:
C:\install>ECHO F | XCOPY /D "C:\install\dummy\dummy.html" "C:\Archive\aa77cd6e-1d19-4eb4-b2a8-3f8fe60daf00.html"
Does C:\Archive\aa77cd6e-1d19-4eb4-b2a8-3f8fe60daf00.html specify a file name or directory name on the target
(F = file, D = directory)? F
C:\install\dummy\dummy.html
1 File(s) copied
I've also verified this command leaves existing files alone. (You should too :-)