batch file : overwrite one file to several existing files - batch-file

I am trying to make simple security program for my company.
We usually make a lot of doc or ppt(x) files and
for some reason, we need to make them disable as soon as possible.
So we usually deleted the all of files but It took so long.
So I thought I can do that by overwritting the files.
If I have a empty doc or ppt files then overwite all of doc, ppt files in working drive each, then it will be faster and much safer than just deleting.
So I tried to use xcopy
Assuming empty.doc is just empty doc file and
xcopy /s /y c:\users\mycom\empty.doc c:\*.doc
But it said cannot perform cyclic copy
I need you guys help
and I am glad to hear suggestion.
Thanks.

This is an old, old batch file that I employed for such an endeavour:
:: dispose.bat
#echo off
:: Check parameter(s), stripping quotes
set yp1=%1
set ydf=
:insistp1
if defined yp1 set yp1=%yp1:"=%
if not defined yp1 for %%i in (echo goto) do %%i error - filename required
if not exist "%yp1%" for %%i in (echo goto) do %%i error - file not found
for %%i in ("%yp1%") do (set yfr=%%i&call :zapit %%~di) 2>nul
:error
:: Clean up variables used
if defined ydf echo Warning! dispose failed!!
for %%i in (yp1 yfr yrn ydf) do set %%i=
goto :eof
:zapit
set yfr=%yfr:"=%
IF /i %1 == u: DEL "%yfr%" &goto :eof
if not exist %1\delete\. md %1\delete
(set yrn=)
:rndloop
set yrn=%yrn%%random%
if exist %1\delete\%yrn% goto rndloop
if not exist "%yfr%" set ydf=Y&goto :eof
move "%yfr%" %1\delete\%yrn%>nul
goto :eof
:: dispose.bat ends
Noting that u: is a RAMDRIVE on my system, hence mere deletion is all that is required.
The purpose is not to actually delete the files, but to move them to a directory named ?:\delete and provide them with a random name in that directory.
Since the file is simply MOVEd it is quite fast, which addresses your time consideration.
An issue for me is the idea of copying a file over all of the files you target. If the file that you copy is shorter than the other files, some data wilstill be available to be recovered. Regardless, it will alwats be slower than simply deleting the files (which you say you are currently doing.)
This scheme simply accumulates the files-to-be-deleted in a known directory on the same drive (so they will simply be moved, not copied.)
Once they are in your \delete directory, you can let a utility like ccleaner or recuva loose on that single directory in the background and it will overwrite the files a specified number of times.

Here's a simpler method. Be careful.
At the command line:
for /r c:\ %A in (*.doc? *.ppt?) do echo. > %A
In a batch file:
for /r c:\ %%A in (*.doc? *.ppt?) do echo. > %%A
EDIT:
To replace with a file, see the example below. Replace the example's d:\path\file.ext with your intended file. Note that the previous option will work much faster with a similar result.
At the command line:
for /r c:\ %A in (*.doc? *.ppt?) do copy d:\path\file.ext > %A
In a batch file:
for /r c:\ %%A in (*.doc? *.ppt?) do copy d:\path\file.ext > %%A
Either way, as noted in Magoo's answer, larger files will still have recoverable data on the drive. You stated in a comment:
But if I overwrite the original files, then they cannot guess what it
was unless they got bak files
This isn't accurate. Forensic tools can retrieve the partial data that wasn't overwritten with new content.

Related

How to delete long name folders under subfolder using batch file

I am trying to delete the sub folders using batch file.
I have folder
c:\users\mis
c:\users\mis\A\Third Party Log
c:\users\mis\B\Third Party Log
c:\users\mis\C\Third Party
c:\users\mis\D\Third Party
Etc.
I want to delete all "Third Party Log" folder and I tire as below:
#echo off
Set MainFolder=C:\users\mis
FOR /D %%D IN ("%MainFolder%\*") DO CALL :RENAME %%D
pause & exit
REM -------------------------------------------------------
:RENAME
Set CRITERIA=Third Party Log
FOR /D %%R IN ("%1\%CRITERIA%") do #if exist "%%R" rd /s /q "%%R"
REM -------------------------------------------------------**
If the folder is only Third it is deleting. Please help me deleting the fodlers.
Thanks,
Htet
#ECHO OFF
SETLOCAL
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "targetdir=u:\your files"
SET "selectname=Third Party Log"
FOR /f "delims=" %%a IN (
'dir /b /s /ad "%targetdir%\%selectname%" '
) DO (
IF /i "%%~nxa"=="%selectname%" ECHO RD /S /Q "%%a"
)
Simply perform a dir /b /ad to list all of the directorynames matching the mask %selectname% and remove all of the hits.
Note that the for loop could be condensed to a single line, but I've split it over a number for clarity.
Naturally, the variables could be substituted by their literal values as well, if desired. This would reduce the entire batch to a single line which could be entered directly at the prompt in which case each %% needs to be reduced to a single %.
Posted code simply echoes the proposed instruction to allow for verification. I the displayed instructions are correct, remove the echo keyword to actually destroy the unwanted directories.
Finally, in your original code, rename is not a good name for the subroutine for two reasons : First, it is misleading as no renaming is being performed and second, ren is an alias of rename - and it's not a good idea to have a routine or variable or label that is itself a command-name.
I can sadly not write code and test it rn but:
You could use the dir command into a temp file.
Use findstr(or find i m not shure) and look for third party log.
Write this back to the temp file.
Now you should be left with a file filled with the paths of the folders you want gone.
Read the file line by line and delete and use this line string to provide the path for the del command.
To change the name as in the sample code you could take the line string and use it as the path to the ren command.
This is most likely a very bad approach but it should work.

Will this be possible with a batch file?

Before I start posting code I am wondering if this is even feasible.
I have a directory of folders I need to move to a new directory.
But I only need to move the folders that contain only 2 files in them.
The rest of the folders have more than 2 files in them, but they need to stay.
So would this be feasible with a batch file?
This was interesting so I took a stab at it:
#echo off
set "dir=C:\Your\Current\Directory"
set "ndir=C:\Your\New\Directory"
setlocal enabledelayedexpansion
for /d %%A in (%dir%\*) do (
pushd "%%A"
for /f %%B in ('dir /a-d-s-h /b ^| find /v /c ""') do (
set cnt=%%B
if "!cnt!" == "2" (if not exist "%ndir%\%%~nA" robocopy "%%A" "%ndir%\%%~nA" /e)
)
)
pause
I kept running into issues so I modified a few things to make it do what I wanted; there're likely more elegant ways to go about it, but this worked ¯\_(ツ)_/¯. First thing is setting variables for your current directory (dir) and your new directory (ndir) to make it a little easier to digest later on; we also need to enable delayed expansion since the value of our counting variable (cnt) will change between loop iterations. The first FOR loop is /d, which will loop through folders - we set each of those folders as parameter %%A and use that to change our directory (using pushd) prior to running our nested commands.
The second FOR loop is /f, which will loop through command results - the commands in this case being dir and find. For dir we are specifying /a to show all files that -d aren't folders, -s system files, or -h hidden files, and we display that output in /b bare format. Using the output from dir, we run find and specify to /v display all non-empty lines and then /c count the number - which becomes parameter %%B.
Finally, we set %%B as our counting variable (cnt) - if !cnt! is equal to 2, we see if the folder already exists in the new directory, and if it does not we robocopy it over. The move command was giving me some trouble because the folder would be locked by the loop, so if you want you could also throw in a DEL command to delete the original folder.
Let me know if that helps! Hopefully your research was going well anyway.
References: Counting Files, FOR Looping, pushd, DIR, FIND, robocopy

Batch: Preserve (creation-)date on copying files to another (flatten) folder structure, incl. renaming files to avoid doublettes

this is my first question, so I apologize beforehand if I write not as you are used to...
fact:
I've a deep folder structure with tons of files (images,videos and so on) so I want to copy that files to a flat structure for a better overview.
I want to keep (at least) the original date attributes: creation-date and last-modified date.
Problem 1) there are files with same name 00001.jpg in different folders which I want to have in same folder, so I want to add creation date/time to filename on copy process.
00001.jpg becomes 2015-11-17_11-23-35_00001.jpg
So far so good. Or not good...
Copy and XCopy doesn't give me an option to do that, without loosing at least the creation date information (I didn`t find a solution with both).
Now I try to copy the files (file by file) with robocopy to new folder and use ren on the copied file to "pre-set" the date/time information before the filename.
Here is a simple test.bat example:
setlocal enableextensions enabledelayedexpansion
robocopy . ./zzz original.txt /copy:DATSO
pause
rem :: formatted creation date of original file will be here, in real life
set "myDate=2015-11-17-_11-23-35"
rem rename "./zzz/original.txt" "!myDate!_renamed.txt" ::doesnt work: why? relative path??
rem :: this will do what I want - original creation date is kept on copy file
FOR %%A IN (zzz/original.txt) DO REN "%%~fA" "!myDate!_%%~nxA"
[possibly] Problem2) Is there a better way to do this, or could I run into thread problems (asynchronous execution). Could it be, that I try to rename a file before the robocopy has finished the copy process (e.g. for large files)?
Sorry I'm a totally batch newbie (also as poster in SO ;).
ThanX in advance for each tip and also for critics on my solution approach. Maybe I have the horse-blinkers on my head and dont see the easy solution?!
[edit: formatting of post]
[edit: content of post -> date/time in front of filename for better sorting]
It is possible to use command DIR to get recursive listed all files in the specified folder and its subfolders with creation date/time.
The format of the date/time depends on Windows Region and Language settings.
Example output for F:\Temp\Test on my machine with English Windows 7 and region is configured to Germany on running the command line dir F:\Temp\Test\* /A-D /S /TC:
Volume in drive F is TEMP
Volume Serial Number is 1911-26A4
Directory of F:\Temp\Test
25.09.2017 17:26 465.950 SimpleFile.ccl
1 File(s) 465.950 bytes
Directory of F:\Temp\Test\Test Folder
25.09.2017 17:26 360.546 Test File.tmp
1 File(s) 360.546 bytes
Total Files Listed:
2 File(s) 826.496 bytes
0 Dir(s) 58.279.460.864 bytes free
This output is filtered with findstr /R /C:"^ Directory of" /C:"^[0123][0123456789]" to get only lines starting with  Directory of (note the space at begin) or with a number in range 00 to 39.
Directory of F:\Temp\Test
25.09.2017 17:26 465.950 SimpleFile.ccl
Directory of F:\Temp\Test\Test Folder
25.09.2017 17:26 360.546 Test File.tmp
And this filtered output is processed by FOR loop and the commands executed by FOR.
#echo off
for /F "tokens=1-2*" %%A in ('dir "F:\Temp\Test\*" /A-D /S /TC ^| %SystemRoot%\System32\findstr.exe /R /C:"^ Directory of" /C:"^[0123][0123456789]" 2^>nul') do (
if "%%A %%B" == "Directory of" (
set "FilePath=%%C"
) else (
set "CreationDate=%%A"
set "CreationTime=%%B"
for /F "tokens=1*" %%I in ("%%C") do set "FileName=%%J"
call :RenameFile
)
)
goto :EOF
:RenameFile
set "NewName=%CreationDate:~-4%-%CreationDate:~3,2%-%CreationDate:~0,2%_%CreationTime:~0,2%-%CreationTime:~3,2%_%FileName%"
ren "%FilePath%\%FileName%" "%NewName%"
goto :EOF
It would be advisable to put command echo before command ren in last but one line to first verify the expected new file names.
ren "F:\Temp\Test\SimpleFile.ccl" "2017-09-25_17-26_SimpleFile.ccl"
ren "F:\Temp\Test\Test Folder\Test File.tmp" "2017-09-25_17-26_Test File.tmp"
Note: The batch file must be in a folder not processed by this batch file as otherwise the batch file itself would be renamed while running which breaks the processing of the batch file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
dir /?
echo /?
for /?
goto /?
if /?
ren /?
set /?
By the way: WinRAR can add files into a RAR archive with creation and last access time in addition to last modification time and extract the files to a different directory with restoring also creation and last access time using SetFileTime function of Windows kernel.
currently I use Locale independent date. I use tokens from that for currrent date/time.
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetime=%%I
rem :: format it to YYYY-MM-DD_hh-mm-ss
set myDateTime=%datetime:~0,4%-%datetime:~4,2%-%datetime:~6,2%_%datetime:~8,2%-%datetime:~10,2%-%datetime:~12,2%
Thats not the problem.
To clarify:
The listing is also not the problem.
I loop throw all related files without a prob (except batch files and output dir and its sub tree ;).
My problem is:
I call robocopy for each file, then I rename the file to save the original creation date. My fear is that it makes problems (Multi-Threading?) for large files and for the number of calls (many thousend times)
Is batch execution really serialized? Is the process waiting for robocopy, that it has finished, before I try to rename file. Could I run into dead-locks for vry large files? I'll test it with some fake gigabyte-files.
Your suggestion, to use winrar sounds interesting.
If I could add all that files to a big archive (with structure) and at the end extract it to target dir... I'll try it ;)
If it doesn't work I will program it in java!
There I know what to do, thats my playground :D
I thought it would be easy to write a simple batch file, to do this for me, but it seems it's not as easy as I thought!
ThanX anyway

SIMPLE :: XCOPY NOT PRODUCING OUTPUT IN .bat

I'm a mortgage loan guy in Seattle, WA and I frequently set up a folder hierarchy into which I save a client's documents and as they come in to me. I've been creating these manually for years and I'd like to save the 3 to 4 minutes it takes to set these up by using a batch file.
So... I have a default set of folders, some of which contain a couple of small Adobe PDFs. What I'd like to do (and cannot make happen) is to run a batch file that would facilitate some custom remarks or input from me during the batch so that with a click and a couple of keystrokes, I have an organized folder setup for a new client within seconds rather than minutes.
I've written the following but it isn't producing any output folders or files.
______not sure character terms show correctly - see linked images below for actual______
#echo off
::Ask
echo Your Source Path:
set INPUT1=
set /P INPUT1=Type input:
echo Your Destination Path:
set INPUT2=
set /P INPUT2=Type input:
C:\WINDOWS\system32\xcopy.exe /e /v %INPUT1% %INPUT2%
My responses were:
to the first prompt "E:\DV8333 MY DOCUMENTS\002 ATLAS\ATLAS RESOURCES\000NEWCLIENTFOLDER2014"
to the second prompt "E:\DV8333 MY DOCUMENTS\001 CLIENTS\"
I have verified that xcopy.exe is in fact located as indicated above.
I'm on XP SP3
My actual paths and .bat file are shown in the linked image for clarity.
http://www.avidrecording.com/images/01.png
Thanks in advance, much appreciated.
#Rem save this as a .bat file and run
#echo off
set /P source=Enter Source Folder:
echo %Source%
set /P destination=Enter Destination Folder:
echo %destination%
xcopy %source% %destination% /v /i /e
Fundamentally, your problem appears to be that the xcopy command can't figure out which of the data it is receiving is parameters and which switches and which superfluous because you have spaces in your directorynames.
Fortunately, the cure is simple. "quote your parameters"
C:\WINDOWS\system32\xcopy.exe /e /v "%INPUT1%" "%INPUT2%"
Now - the path to xcopy.exe is probably superfluous - as is the extension, so
xcopy /e /v "%INPUT1%" "%INPUT2%"
is more than likely all you'd need.
(I'd caution to experiment with a throw-away destination until you've perfected your method. I use a RAMDISK...)
Also, if you're copying a template, then there's no apparent reason for all the folderol about inputting Input1. If you have more than one template set, set up a separate batch and shortcut for each one with a fixed template path, eg
xcopy /e /v "E:\DV8333 MY DOCUMENTS\002 ATLAS\ATLAS RESOURCES\000NEWCLIENTFOLDER2014" "%INPUT2%"
Note the use of quotes to defeat the evil spaces.
Next, your destination could be built, but may contain spaces. For instance, you may have a client to which you wish to refer as "037 - Fred Nurk". Now it's a pain to have to type in the full path, so make it easy. Just type in the 037 - Fred Nurk part and let batch fill in the rest.
xcopy /e /v "E:\DV8333 MY DOCUMENTS\002 ATLAS\ATLAS RESOURCES\000NEWCLIENTFOLDER2014" "E:\DV8333 MY DOCUMENTS\001 CLIENTS"\"%input2%"\
Note that this will append the input as a directory under E...001 clients. Note that the strings are concatenated and the double-quotes are there solely to tell batch "here be a string that may contain spaces."
If this works, and there's no reason why it wouldn't (does for me...) then all you'd need to do is enter the client details and the template would be copied to a new directory. Now actually playing around with the data in the files that are copied so that they are customised - well, at the price, that would be worthy of another question...
#echo off
echo Backing up file
set /P source=Enter source folder:
set /P destination=Enter Destination folder:
set /P Folder name=Enter Folder name
set xcopy=xcopy // Set the switches as per your need
%xcopy% %source% %destination%
pause

Deleting folders and subdirectories when a file extension is found in it

I'm new to the board so please go easy! :)
Basically, I'm writing a batch file to delete folders that don't have a file with a certain extension type in them.
so for example if i have the following folder
C:\MUSIC\FLAC\JAZZ\Jazzysong.ape
I need a bit of code that can delete the folder JAZZ because .ape is the wrong file type for the FLAC folder.
Any help would be awesome guys as I've tried variants of findstr, exist and writing to text file and trying to read the path using dir /s /b
I'm lost
I'm still unsure as to which kind of test you want to perform on a directory before deciding to remove it – "whether a certain file type exists" or "whether a certain file type doesn't exist". Your post seems to suggests it is the latter, so it must be the title that is misleading. For the purpose of this answer, I'm assuming that it is indeed the "whether a certain file type doesn't exist" test that you want.
Here's a very simplistic and unassuming approach to the problem:
#ECHO OFF
FOR /D /R "D:\directory_with_flac_files_only" %%D IN (*) DO (
IF NOT EXIST "%%D\*.flac" ECHO RD /S /Q "%%D"
)
That is, just traverse the directory tree and, for every subdirectory, check if it doesn't contain the necessary files. If it doesn't, say goodbye to it. (For safety, I added ECHO before the RD command, so that it does indeed say its goodbye but does not perform the real action, just in case you rush into executing the script without reading further.)
That approach is wrong, however. Even though a directory may not contain the required files, its sub-directories might, and this script does not verify that fact. As a consequence, you might lose some of your invaluable FLAC files. (And I've just saved you the grief.)
So, something more elaborate is needed here. The method I came up with consists in the following steps:
Sort the directories into two categories: those that contain the files with the necessary extension and those that don't.
Process the list of directories that do not contain the files:
1) if a directory is found in the other list, omit it;
2) if it is not found in the other list, remove it.
(In case you are wondering: a directory from the first list may indeed be found in the second list as part of its subdirectory's path.)
I'm far from being convinced that it's the best approach possible, but at least it should work (it did work for me, anyway). Here's my implementation of it:
#ECHO OFF
:: set the params
SET "ext=flac"
SET "rootdir=D:\dir_with_flac_files_only"
SET "todelete=%TEMP%\dirs_to_delete.txt"
SET "topreserve=%TEMP%\dirs_to_preserve.txt"
:: clear the temp lists
TYPE NUL >"%todelete%"
TYPE NUL >"%topreserve%"
:: sort the dirs
FOR /D /R "%rootdir%" %%D IN (*) DO (
IF EXIST "%%D\*.%ext%" (
ECHO %%D>>"%topreserve%"
) ELSE (
ECHO %%D>>"%todelete%"
)
)
:: process the sorted lists
FOR /F "usebackq delims=" %%D IN ("%todelete%") DO (
FIND "%%D" <"%topreserve%" >NUL || ECHO RD /S /Q "%%D" 2>NUL
)
You can still see the ECHO before RD, but consider it just my way of saying, ‘In case I missed something…’. Run the script and look at the output. If it correctly shows only the directories that are due to be deleted, remove ECHO and run the script again to get on with the action.

Resources