I need to move certain files to another folder based on modified date.
I came up with the following batch script for the move.
#ECHO OFF
SetLocal EnableDelayedExpansion
set "FolderA=D:\IN\Set1"
set "FolderB=D:\IN\Set2"
set "FolderC=D:\OUT\"
for /f "tokens=2 delims=," %%a in (D:\input.txt) do (
Xcopy "!FolderB!\%%~a" "!FolderC!\"
Echo Copied "%%~a" to "!FolderC!"
)
for /f "tokens=1 delims=," %%a in (D:\input.txt) do (
Xcopy "!FolderA!\%%~a" "!FolderC!\"
Echo Copied "%%~a" to "!FolderC!"
)
The input.txt contains file names as:
file1.dat,file_abcd_efgh_ijklmnop02-2014.dat
file2.dat
file3.dat
The destination, FolderC, should actually be set as D:\OUT\2014\P02 which is based on file_abcd_efgh_ijklmnop02-2014.dat --> (2014, 02).
While moving from FolderB to FolderC, we should check if file has modifed date within past 34 days. If so, and the file name is file_abcd_efgh_ijklmnop02-2014.dat, check if a folder D:\OUT\2014\P02 exists, else create it.
While moving from FolderA to FolderC, the files should be checked for modifed date within past 34 days, and should be moved to D:\OUT\2014\P02.
Thanks.
Related
I have a folder of PDF files that have a consistent naming convention. I want to create a zip file of these PDF files but named the zip file using the portion of the file that is before the # -- all of the files are the same in the front (it is the NTID of the user that created the pdf files).
As an example these are what the files might look like in the PDF output folder (there could be 100 files all that start with the same UserID before the #:
UserID#Carlos+Alberto+Mafra-+bribery-2019-05-16
UserID#MAJELA+HOSPITALAR+LTDA-+bribery-2019-05-16
(Ideally, I would also want the current date appended to the zip file)
The zip should be called UserID-2019-05-16.zip based on the example above.
This is the code I am trying to use but not having success...
I created a batch script using others suggestions for each step. but can't get it to work end to end.
FOR %%F IN ("C:\Users\SA-JJC-HCC_Ops\OneDrive - JNJ\workflows\TPIGoogle\pdf\*.pdf") DO (
set filename=%%F
goto next
)
:next
echo "%filename%"
set zipfile=%filename%
for /f "tokens=1 delims=#" %%a in ("%zipfile%") do (
)
cd "C:\Program Files\7-Zip\"
7z.exe" a "C:\Users\SA-JJC-HCC_Ops\JNJ\HCC&P Alteryx - Documents\EPiC\GoogleSearches\zip\" && %zipfile% && ".zip" "C:\Users\SA-JJC-HCC_Ops\OneDrive - JNJ\workflows\TPIGoogle\pdf\*.pdf"
One zip file with all the PDFs that are using the first part of the string from the file names in the PDF folder.
#ECHO OFF
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
FOR /f "tokens=1*delims=#" %%a IN (
'dir /b /a-d "%sourcedir%\*#*-????-??-??.pdf" '
) DO (
SET "pre=%%~a"
SET "post=%%~nb"
SET "post=!post:~-10!"
IF DEFINED post ECHO "C:\Program Files\7-Zip\7z" a "%destdir%\!pre!-!post!.zip" "%sourcedir%\%%~a#%%~b"
IF NOT DEFINED post ECHO SKIP "%%~a#%%~b"
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
I used the variablenames pre and post to ensure that the names used in this process are not keywords like the more logical date.
Read a list of all filenames matching the pattern *#*-????-??-??.pdf in the source directory, tokenising on #. Assign the userid to %%a and thence to pre and the "name" part of the dregs of the actual filename to post, then select only the last 10 characters of post using delayed-expansion.
There is an opportunity here to further process post to check whether it truly fits the pattern for a date, if that is required. That routine may return post either unmolested or empty. If it's not empty then construct the required 7z command (you may wish to add -tzip) and echo this for verification - remove the echo to actuate the 7z compression. If post is emptied by a pattern-checking routine, then the filename will simply be reported as having been skipped.
If it is indeed current date you want to append to the end of the zip file, then we need to get the non locale dependent date and time. This will then copy each of the pdf files that starts with UserID to a zip with a date of the day you run the script UserID-2019-05-17 :
#echo off
set "outDir=C:\Users\SA-JJC-HCC_Ops\JNJ\HCC&P Alteryx - Documents\EPiC\GoogleSearches\zip\"
set "inDir=C:\Users\SA-JJC-HCC_Ops\OneDrive - JNJ\workflows\TPIGoogle\pdf\"
for /f "tokens=1,2 delims==" %%i in ('wmic os get LocalDateTime /VALUE') do (
if ".%%i."==".LocalDateTime." set mydate=%%j
)
set mydate=%mydate:~0,4%-%mydate:~4,2%-%mydate:~6,2%
for %%a in (*.pdf) do for /f "delims=#" %%i in ('dir /b /a-d %%a') do (
"C:\Program Files\7-Zip\7z" a "%outDir%%%i-%mydate%.zip" "%inDir%%%~a"
)
If in fact you want to append the date of the filename instead (In other words create Zip files for each file with a different date as well as matching userid):
#echo off
setlocal enabledelayedexpansion
set "outDir=C:\Users\SA-JJC-HCC_Ops\JNJ\HCC&P Alteryx - Documents\EPiC\GoogleSearches\zip\"
set "inDir=C:\Users\SA-JJC-HCC_Ops\OneDrive - JNJ\workflows\TPIGoogle\pdf\"
for %%a in (*.pdf) do for /f "tokens=1,* delims=#" %%i in ('dir /b /a-d %%a') do (
set fdate=%%~nj
set fdate=!fdate:~-10!
echo "C:\Program Files\7-Zip\7z" a "%outDir%%%i-!fdate!.zip "%inDir%%%~a"
)
Found a pyhton solution here, but I need a batch file-based solution.
Have many files:
SSP4325_blah-blah-blah.xml
JKP7645_blah.xml
YTG6457-blah-blah.xml
And folder names that contain a piece of the file name:
RefID - SSP4325, JKP7645, GHT1278, YRR0023
RefID - YTG6457
I'm looking for a batch solution which would read a portion of the file name at the front (before either the first dash or underscore) and then move that file into the folder where the front of the filename exists as part of the folder name.
So in the above examples, the first two files (SSP4325 and JKP7645) were moved into the first folder because it contained it contained that text as part of the folder name.
The third file would be moved into the second folder.
I have hundreds of files and 63 folders. So I'm hoping to be able to automate.
Can't use Powershell or Python due to limitations of the environment. So hoping for a batch file approach.
Thanks. Sean.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*.xml" '
) DO (
FOR /f "tokens=1delims=_-" %%b IN ("%%a") DO (
FOR /f "delims=" %%d IN (
'dir /b /ad "%destdir%\*%%b*" '
) DO (
ECHO(MOVE "%%a" "%destdir%\%%d\"
)
)
)
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
After establishing the directories, the outer loop puts the filename in %%a, the next loop gets the first part of that name, up to but not including the first - or _ (the delims specified) into %%b.
The inner loop finds the target directory containng %%b in the destination directory and constructs an appropriate move line.
This solution review the folders just one time and store they in an array, so this method should run faster.
#echo off
setlocal EnableDelayedExpansion
rem Process the folders
set i=0
for /D %%a in (*) do (
rem Store this folder in the next array element
set /A i+=1
set "folder[!i!]=%%a"
rem Separate folder in parts and store the number of the array element in each one
for %%b in (%%a) do set "part[%%b]=!i!"
)
rem Process the files
for %%a in (*.xml) do (
rem Get the first part of name
for /F "delims=-_" %%b in ("%%a") do (
rem If such a folder exists...
if defined part[%%b] (
rem Get the number of the corresponding array element and move the file
for %%n in (!part[%%b]!) do ECHO move "%%a" "!folder[%%n]!"
) else (
echo No folder exists for this file: "%%a"
)
)
)
This method have also several advantages: you may check if a certain folder does not exists, or get the number of files moved to each folder, etc. If you are not interested in these points, just remove the if command and make the code simpler...
An explanation of array management in Batch files is given at this answer.
I have a folder that gets a new file added everyday to the folder with the same file name but incremental extension such as .001, .002, .003, etc. However, if there's no file within the folder it starts at .001 again.
The problem is they are all named the same and if I move them to another folder to archive them it would just overwrite the same file over and over again. I could create a folder each day with the date with only one file in it, but that seems a bit redundant.
Is there a way to look at the create date of each file and rename it to the create date?
I've gotten this far, but it looks like for this situation I have to use a static file name, how to loop through the entire directory?
SET filename = C:\test.001
FOR %%f IN (%filename%) DO SET filedatetime=%%~tf
rename c:\test.001 C:\test_%filedatetime%.txt
move C:\*.txt C:\archive\
this provides the correct sort order:
#echo off &setlocal disableDelayedExpansion
set "startfolder=%userprofile%\test"
cd /d "%startfolder%"
for %%a in (*) do (
for /f "delims=." %%b in ('wmic datafile where "name='%startfolder:\=\\%\\%%~a'" get lastmodified^|find "."') do (
echo(ren "%startfolder%\%%~a" "%%~b.txt"
)
)
Remove echo to get it working.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "targetdir=c:\sourcedir"
SET "destdir=c:\destdir"
PUSHD "%targetdir%"
FOR %%a IN (*.*) DO (
SET "timestamp=%%~ta"
SET "timestamp=!timestamp:/=_!
SET "timestamp=!timestamp::=_!
SET "timestamp=!timestamp:.=_!
SET "timestamp=!timestamp:,=_!
SET "timestamp=!timestamp: =_!
ECHO MOVE "%%a" "%destdir%\%%~na.!timestamp!"
)
GOTO :EOF
This should work with any file in the nominated target directory where the name does not include ! or ^.
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
The gymnastics around timestamp are intende to replace /: with _ since these are illegal filename characters. Space., are similarly replaced - they're legal but often painful.
If you want the destination filename to be name.003.timestamp, remove the ~na from the destination name.
Try like this :
SET $path=The_path_who_contain_the_FILES
FOR /F "DELIMS=" %%f IN ('dir "%$path%" /a-d/b') DO (
SET filedatetime=%%~tf
move "%%~dpnxf" "C:\archive\test_%filedatetime%.txt")
Ok let me explaned it again
I have two location :
F:\Reporting\02.2013 in the folder "02.2013" I have below files
Balance Sheet_20130228_045485.xls 3/22/2013 2:40 PM
Balance Sheet_20130228_024867.xls 3/23/2013 1:40 PM
Balance Sheet_20130228_023556.xls 3/23/2013 3:50 PM
F:\Statements\02.2013 in the folder "02.2013" I have below files
FS_20130228_045485.xls 3/22/2013 4:40 PM
FS_20130228_024867.xls 3/23/2013 1:40 PM
FS_20130228_023556.xls 3/23/2013 6:45 PM
First I wants to moov the latest modified files from both the folder to Target folder :
Target folder is F:\accounting\02.2013
Then I wants to rename those files as
Balance Sheet_20130228_023556.doc as BalanceMTD.xls
FS_20130228_045485.doc as FS.xls
note: I have to do this activity every month,
so folder location will be change like F:\Reporting\03.2013
and file name also will be change like FS_20130331_045465.doc 4/27/2013 4:30 PM
Can you please suggest me any batch file which can help me to do this.
I'll change the date every month if required before execute it.
This will move and rename the newest file from each of your source directories:
#echo off
setlocal
set DateFolder=02.2013
set TargetFolder=F:\Accounting\%DateFolder%
:: Move the newest file from Reporting and rename it to BalanceMTD.xls
call :MoveAndRename "F:\Accounting\%DateFolder%" "%TargetFolder%\BalanceMTD.xls"
:: Move the newest file from Statements and rename it to FS.xls
call :MoveAndRename "F:\Statements\%DateFolder%" "%TargetFolder%\FS.xls"
:: Done
goto :eof
:MoveAndRename
set SourceFolder=%~1
set TargetFile=%~2
:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set "NewestFile=%%F"
:: Move and rename it to the target
move "%SourceFolder%\%NewestFile%" "%TargetFile%"
:: Done with this subroutine
goto :eof
I've put the bulk of the working code in a "subroutine" named MoveAndRename, which simply finds the newest file in a particular folder (using a for /f loop over a dir /a-d to loop over all files in order of date, remembering only the last one), then a move to move and rename it to the target. (If you want to keep the original file, then do copy instead.)
The top part of the batch file then just calls the MoveAndRename subroutine multiple times, once for each source folder you want to look at.
If you want to avoid editing the batch file every month, change the third line to this:
set DateFolder=%1
and pass the date to the batch file as an argument: MonthlyProcess.bat 02.2013. Or you can set DateFolder using the %date% environment variable, but since it is formatted based on your locale settings, and it is well documented elsewhere, I will leave that as an exercise for you.
#echo off
setlocal EnableDelayedExpansion
cd F:\MY DOCUMENTS\zyx
rem Process all file names
for /F "delims=" %%a in ('dir /B *.xls') do (
rem Get base name before first underscore (ie: "Balance Sheet" or "FS")
for /F "delims=_" %%b in ("%%a") do (
rem Check if name have two words (ie: "Balance"/"Sheet" or "IC"/"Activities")
for /F "tokens=1,2" %%c in ("%%b") do (
rem If base name have just one word...
if "%%d" equ "" (
rem New name is that word (ie: "FS")
set newName=%%c
) else (
rem We don't know what goes here!
)
)
)
ren "%%a" "!newName!.xls"
)
We could complete previous program if you give us details on how to do so...
I have managed to copy and manipulate a batch script that does the following:
looks at the last 4 characters of a .csv file
creates a folder with this name
moves the file into the folder
#echo off & setlocal EnableDelayedExpansion
echo.
pushd "%~dp0"
for %%j in (*.csv) do (
set file=%%~nj
set folder=!file:~-4!
if !folder!==FI_2 set folder=!file:~-6!
if not exist !folder! md !folder!
move "%%~j" "!folder!"
echo "%%~j" -^> "!folder!"
)
popd
echo.& echo.Done
:: End_Of_Batch
The problem I have is that I need to group the files by month. The file names look like this:
BS_IDX_LEVEL_YYYYMMDD_BAFI.csv
(obviously the YYYYMMDD will be replaced with the date of the file)
So any file with the name BS_IDX_LEVEL_20111231_BAFI.csv would go into a folder named "1112" (date formate of folder is YYMM)
A file with the name BS_IDX_LEVEL_20111115_BAFI.csv would go into a folder names "1111"
Is there someway I can alter this script so that before organising the files by their filenames it groups them by date first?
If I can explain anything further please let me know
While you are looping through and getting the last 4 characters of the file name, you can also look at the dates. I didn't know if the start of the file will be fixed or subject to change, but I thought it reasonable to assume the date_end syntax would be consistent.
set filedate=!file:~-9,-7!
This will extract the characters between 9th and 7th from the end of the String stored in !file!. With the syntax you have, the will be the two digit month number. This will also avoid any confusion with 2 or 4 digit dates.
Once you have both this and the other folder name, you can simply create both folders at once and place the file directly into the subfolder, so you will still only need to make one pass over the fileset.
#echo off & setlocal EnableDelayedExpansion
echo.
pushd "%~dp0"
for %%j in (*.csv) do (
set file=%%~nj
set folder=!file:~-4!
if !folder!==FI_2 set folder=!file:~-6!
set filedate=!file:~-9,-7!
SET datefolder=!folder!\!filedate!
if not exist !folder! md !folder!
if not exist !folder!\!filedate! md !folder!\!filedate!
move "%%~j" "!datefolder!"
echo "%%~j" -^> "!datefolder!"
)
popd
echo.& echo.Done
:: End_Of_Batch