Under the path U:\test\0014* I have 99 folders and each of them has respectively 2 subfolders MASTER and DERIVATIVE_COPY. With a following script I try to count the number of PDFs in MASTER folder. If there are only one .pdf file there I want to copy it to DERIVATIVE_COPY folder. IF there are 0 or >1 .pdf in MASTER I want only to show the number of them. This operation should be done for each of the 99 folders.
#echo off
setlocal enabledelayedexpansion
for /R U:\test\0014\*\MASTER %%i in (*.pdf) do (
set /a anzahl+=1
)
if !anzahl! EQU 1 ( echo !anzahl! )
if NOT !anzahl! EQU 1 ( echo !anzahl! )
pause
#ECHO OFF
SETLOCAL enabledelayedexpansion
SET "sourcedir=U:\sourcedir"
for /f %%i in ('dir /ad /s/b "%sourcedir%\master*"') do IF /i "%%~nxi"=="MASTER" (
SET /a found=0
FOR %%x IN ("%%i\*.pdf") DO SET /a found+=1
IF !found!==1 (
XCOPY /y "%%i\*.pdf" "%%i\..\derivative_copy\" >nul
) ELSE (
ECHO !found! .pdf files found IN "%%i"
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
First, execute a dir to get a directory-list of the "files" names that start master in the specified tree. Use /ad to select only the directory-names. Accept only those names where the "name+extension" is master (disregarding case)
For each directory-name found, set found to 0 then increment found for each .pdf file found in the directory %%i.
If the resultant count in found is 1, xcopy the file found to the destination subdirectory (which conveniently creates the subdirectory if it doesn't already exist), using /y to overwrite any existing file of the same name and >nul to make the process silent.
Otherwise, report the directoryname and count of files.
Related
I'm writing a batch file to compare the contents of two folders on a network drive. A new folder is generated every night by a macro and I want to see what changed between today and yesterday. For example, if yesterday's folder is called "B" and today's folder is "A" and their structure looks like:
- Home
- A
- file1.txt
- file2.txt
- file4.txt
- B
- file1.txt
- file2.txt
- file3.txt
I would want to see something like
A: file4.txt added
A: file3.txt removed
But the format of the output doesn't really matter at the end of the day. I just need to see a comparison of the folder's contents.
What I have so far
Using my limited batch knowledge, I've smashed together this currently non-working solution:
#ECHO OFF
setlocal EnableDelayedExpansion
pushd "\\domain\path\to\Home"
set "j=0"
set "count=2"
:: get the names of the two most recently added folders
FOR /f "delims=" %%i IN ('dir /AD-H /B /O-D') DO (
set /A j=j+1
if !j! equ 1 (
:: send contents of newest folder to file
dir !i! /B > newest_folder.txt
)
if !j! equ 2 (
:: send contents of second-newest folder to file
dir !i! /B > older_folder.txt
)
if !j! geq !count! (
:: break after two folders
goto :end
)
)
:end
fc newest_folder.txt oldest_folder.txt
PAUSE
I saw a similar solution here:
(for %%i in ("folder2\*") do if exist "folder1\%%~nxi" echo(%%~i)>file.csv
But it wouldn't work in my case because the folder names change every day.
Any help would be appreciated!
#ECHO OFF
setlocal EnableDelayedExpansion
set "later="
set "earlier="
pushd "\\domain\path\to\Home"
:: get the names of the two most recently added folders
FOR /f "delims=" %%i IN ('dir /AD-H /B /O-D') DO (
if defined later set "earlier=%%i"&goto report
set "later=%%i"
)
:report
if defined earlier (
dir /b "%earlier%">older.txt
dir /b "%later%">newer.txt
fc older.txt newer.txt
) else echo too few directories found
pause
popd
would be my approach, setting later and earlier to the names of the first two directories found by the dir command.
---- afterthought
if the fc command is replaced by
echo files added
findstr /x /v /g:"older.txt" "newer.txt"
echo files deleted
findstr /x /v /g:"newer.txt" "older.txt"
then your report should be more easily interpreted.
findstr options /x does an exact match, /v reports NON-matches and /g:filename specifies a file containing strings against which to match.
hope you can help me with this, i can't make it work what i need
I need to copy all the .pdf files from a source folder, create a folder with part of the name "T-123456" and add the respective PDF files found in the correct folder in the destination folder, but sometimes the name it varies or the reference change "SM17-123".
Example of files
HC002T-1234562436787004332
MV002T-1234562436787004332
PP _002_T-123456_24_3678_7004332
Types of direfents files
HC123CLG-32-172436787004259
HC123SM17-1802436787004044
i have this code created but it makes part of the job because the name varies and create folders incorrect for that files, sometimes the files have more digits in the beggining example 001 or 0001, so i dont know how to omit the other references files and only work whith files "T-123456" also i need the batch continuously working for new files created in the source folder and if i have another routhe where i have other types of file and copy to the correct reference it would be great.
#echo off
title Electronic File
:loop
cls
timeout -t 1 >nul
color b
for %%A in (*.pdf) do (
echo File Found %%A
for /f "delims=" %%B in ("%%A") do set fname=%%~nB
for /f "delims=" %%C in ("%%A") do set fextn=%%~xC
for /f "tokens=1* delims=" %%D in ("!fname:~5,8!") do set folname=%%D
echo Name folder !folname!
if not exist "!folname!" (
echo Folder !folname! dont exist, creating
md "!folname!" 2>nul
) else (
echo Folder !folname! exists
)
echo Copying file %%A to folder !folname!
xcopy "%%A" "!folname!"
)
echo on
md "C:\test %All%"
xcopy /s /y "X:\test\pdf" "W:\Electronic File %All%"
goto :loop
pause
for %%A in (*.pdf) do (
echo File Found %%A
set fname=%%~nA
set fextn=%%~xA
set folname=!fname:~5,8!
ECHO !folname!|FINDSTR /i /r "[A-Z]-[0-9][0-9][0-9][0-9][0-9][0-9]" >NUL
IF ERRORLEVEL 1 (
ECHO %%A - !folname! excluded
) ELSE (
echo Name folder !folname!
if not exist "!folname!" (
echo Folder !folname! dont exist, creating
ECHO md "!folname!" 2>nul
) else (
echo Folder !folname! exists
)
echo Copying file %%A to folder !folname!
ECHO xcopy "%%A" "!folname!"
)
)
Here's the meat of the matter. delayedexpansion needs to be on - you don't show that in your original code.
Note that there is no requirement for %%B, %%C, %%D as within the loop, %%A contains the filename and hence you can set the variables from that name.
Note that fextn will apparently always be .pdf since that is the extension you specify in your filemask *.pdf so setting it seems superfluous.
The syntax SET "var=value" (where value may be empty) may be used to ensure that any stray trailing spaces are NOT included in the value assigned.
The change I've introduced is to echo the directoryname to findstr, searching /i case-insensitively for /r a regular-expression which is one letter, a dash and then 6 numerics. If the directoryname matches then errorlevel will be set to 0 by findstr, otherwise, it will be set to 1.
The if errorlevel 1 means "if errorlevel is 1 or greater" and if that is so, the match was UNsuccessful, so report the filename and extracted directoryname; otherwise, go through your logic (I've changed it to simply echo the md and xcopy commands, for testing).
Given that we now have a variable structure,
for %%A in (*.pdf) do (
echo File Found %%A
set "copied="
set fname=%%~nA
set fextn=%%~xA
set folname=!fname:~5,8!
ECHO !folname!|FINDSTR /i /r "[A-Z]-[0-9][0-9][0-9][0-9][0-9][0-9]" >NUL
IF not ERRORLEVEL 1 call :process "%%A"
rem repeat this section for each match required - begin
if not defined copied (
set folname=!fname:~5,9!
ECHO !folname!|FINDSTR /i /r "[A-Z][A-Z][A-Z]-[0-9][0-9]-[0-9][0-9]" >NUL
IF not ERRORLEVEL 1 call :process "%%A"
)
rem repeat this section for each match required - end
if not defined copied ECHO %%A - !folname! excluded
)
goto :eof
:process
echo Name folder %folname%
if not exist "%folname%" (
echo Folder %folname% dont exist, creating
ECHO md "%folname%" 2>nul
) else (
echo Folder %folname% exists
)
echo Copying file %~1 to folder %folname%
ECHO xcopy "%~1" "%folname%"
set "copied=Y"
goto :eof
In your extended examples, it's not clear where the PP fits into the scheme.
The formula is reasonably simple. The start position is the first argument in the set (counting from first character=0) and the second the length to select. The regex match may be either a single character (matched literally) or [rangestart-rangeend] . matches any one character, so the first block I've shown selects from HC123CLG-32-172436787004259 from the 5th character (starting at 0) for 9 characters =CLG-32-17 and matches this against alpha,alpha,alpha,-,numeric,numeric,-,numeric,numeric.
On a match, errorlevel is set to 0, so the :process subroutine is called, with a parameter of %%A in quotes. The subroutine uses the value in folname and copies the file (name now in %1 - %~1 removes the quotes) as before.
So - it's as simple as repeating the block of code, altering the start and length of the string to be selected and changing the regex to suit the required pattern.
I need a way to make a directories containing the filename, but counting +1 for every one created.
How can i add +1 in front of the directory name created
Eg:
if Directory 1_xxx is present make 2_xxxxx
Currently i am using below to create a directory from Filename
File name Eg: Card_24ALL Sms.csv
Directory Output Eg: Card_24ALL Sms
Currently i have directories adding +1 manually 1_
1_Card_24ALL Sms ( With File Card_24ALL Sms.csv copied inside)
2_Card_25ALL Sms ( With File Card_25ALL Sms.csv copied inside)
3_Tjek_24ALL Sms ( With File Tjek_24ALL Sms.csv copied inside)
Using the below Code i can get directory added containing the given filename:
#echo off
for %%a in (*.csv) do (
md "%%~na" 2>nul
move "%%a" "%%~na"
)
But I have to manually create the number in front to get number_directory as the number in front can be 99_
Try this:
#echo off
setlocal enabledelayedexpansion
#echo off
cd /d c:\temp
if exist cnt.txt for /f %%a in (cnt.txt) do set %%a
for %%a in (*.csv) do (
set /a cnt+=1
echo md "!cnt!_%%~na" 2>nul
echo move "%%a" "!cnt!_%%~na" >nul && (
Echo File %%~nxa moved to !cnt!_%%~na) || (Echo Move failed.)
)
>cnt.txt echo cnt=!cnt!
Remove the echo's from md and move once you verify the output.
I'm trying to copy some files from one directory to two other directories, using batch.
First i'm making 3 directories and after that, i want to copy the following files to backup1 and backup2.
The files are named 010101.txt - 300101.txt (To backup1) and 010102.txt - 300102.txt (backup2).
mkdir backup1
mkdir backup2
mkdir backup3
copy 1.txt C:\User\Test\Backup1
copy 2.txt C:\User\Test\Backup2
I guess i have to use wildcard somehow, but if i write ?????1.txt and ?????2.txt i get an syntex error.
Try this out:
#echo off
setlocal enabledelayedexpansion
cd /d "C:\Temp\copytest"
set "b1=C:\Temp\Backup1"
set "b2=C:\Temp\Backup2"
for /l %%a in (1,1,300102) do (
set num=%%a
if %%a GTR 10000 if %%a LSS 100000 set num=0%%a
if !num:~-1! EQU 1 (
if exist !num!.txt echo copy !num!.txt %b1%
) ELSE (
if !num:~-1! EQU 2 (
if exist !num!.txt echo copy !num!.txt %b2%
)
)
)
Change paths where applicable. Remove the echos after verifying the output is correct to do the actual copy.
Edit: Simpler way
Copy *1.txt "C:\User\Test\Backup1"
Copy *2.txt "C:\User\Test\Backup2"
#ECHO OFF
SETLOCAL
SET "sourcedir=."
FOR %%b IN (1 2) DO (
FOR /f "delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*.txt" ^| find /i "%%b.txt" '
) DO (
XCOPY "%sourcedir%\%%a" "c:\user\test\backup%%b\" >nul
)
)
GOTO :EOF
I've assumed you want all files in the directory that contain 1.txt to be copied to ...\backup1 and those that contain 2.txt to ...\backup2.
I used my current directory for testing. You'd need to change the value assigned to 'sourcedir' to suit yourself.
Note that the xcopy will create the destination directory if necessary.
I need a batch script to copy files from a random subfolder of a specific directory into a destination directory.
For example, there will be a number of files in their own subdirectory, for example
.../source/a/file.txt
.../source/b/file.txt
So there a number of these files, and I would like to randomly select one of them and have it copied into the new directory
.../destination/file.txt
So the file.txt in the destination is just being overwritten with other files that have the same name but different content.
I'm new to batch scripting and I can't quite figure out how to select each file from a random subfolder. I'd also like it to repeat every 30 seconds until I terminate the script, but I think it should be easy enough to just make a second script that calls this .bat file every 30 seconds once I get it going.
Thanks!
This can do what you request. Just set your source directory, destination directory, and your file name filter.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
pushd "...\source\"
:: Enumerate Files. Method 1
set "xCount=0"
for /r %%A in (file.txt) do if exist "%%~A" set /a "xCount+=1"
echo %xCount%
:: Select a Random File.
set /a "xIndex=%Random% %% %xCount%"
echo %xIndex%
:: Find an Copy that File. Method 1
set "xTally=0"
for /r %%A in (file.txt) do if exist "%%~A" (
if "!xTally!" EQU "%xIndex%" (
xcopy "%%~fA" "...\destination\file.txt" /Y
goto End
)
set /a "xTally+=1"
)
:End
popd
endlocal
pause
Type xcopy /? to see all of its options.
Here are some alternate loop methodologies for the file enumeration.
:: Enumerate Files. Method 2
set "xCount=0"
for /f %%A in ('dir *.txt /a:-d /s ^| find "File(s)"') do set "xCount=%%~A"
echo %xCount%
:: Find an Copy that File. Method 2
set "xTally=0"
for /f "delims=" %%A in ('dir *.txt /a:-d /b /s') do (
if "!xTally!" EQU "%xIndex%" (
xcopy "%%~fA" "...\destination\file.txt" /Y
goto End
)
set /a "xTally+=1"
)
Enjoy :)
#echo off
setlocal EnableDelayedExpansion
rem Enter into the directory that contain the folders
pushd \Fullpath\source
rem Create an array with all folders
set i=0
for /D %%a in (*) do (
set /A i+=1
set folder[!i!]=%%a
)
rem Randomly select one folder
set /A index=(%random%*i)/32768 + 1
rem Copy the desired file
copy "!folder[%index%]!\file.txt" "\Fullpath\destination" /Y
rem And return to original directory
popd
The features of batch script is
It copies all files from source to destination folder with similar structure(even retains empty folders).
Can retain N number of days recent files in Archive folder(source) remaining files will be moved to backup folder(destination).
Can be scheduled to N number of days to N number of years.
Can be used in any Source to destination folder backup.
Source folder can add N number of folder any time and delete folder or files, but Destination folder always adds the folder and never deletes any folder or file.
#echo off
Set "sourcefolder=E:\Interfaces"
Set "destinationfolder=E:\BackupInterface"
If Exist %sourcefolder% (
For /F %%* In ('Dir /b /aD "%sourcefolder%" 2^>nul') do (If Not Exist "%destinationfolder%\%%*" ( RD /S /Q "%destinationfolder%\%%*")
xcopy /e /v /i /y /q "%sourcefolder%\%%*" "%destinationfolder%\%%*"
forfiles /p "%sourcefolder%\%%*" /s /d -30 /c "cmd /c del /Q /S #file" )
) Else (echo.Source folder could not be found)
:end of batch
echo.&echo.finished!