Use a particular drive if path exists in a batch script - batch-file

I have a batch file that sometimes people run and since batch files don't allow UNC mapping, they need specific drive mappings.
The problem is that some people who run this file will have the server mapped to different letters, specifically M or P.
So what I want to do is make a variable to score the drive so I can concatenate it into other path commands where possible because sometimes they will have:
M:\Path\to\stuff\on\server
or
P:\Path\to\stuff\on\server
So what I want to do is say if M:\Path\to\stuff\on\server" exists then use drive M, if "P:\Path\to\stuff\on\server" exists then use drive P.
Is there a way to do this in batch script?

Seeing as you specifically only have M: and P: in this example:
#for %%i in (m: p:) do #if exist %%i cd /d %%i
echo %cd%
It can be extended to more drives. Additionally please note that if the user has both M:\ and P:\ drives, it will cd to both and end up in the last one in the list. Therefore using a known directory is a better solution on the mapping.
#for %%i in (m: p:) do #if exist "%%i\Path\to\stuff\on\server" cd /d "%%I\Path\to\stuff\on\server"
echo %cd%
if you want to set it as a variable to use it anywhere else in the script, then simply assign the drive letter to a variable like so:
#for %%i in (m: p:) do #if exist %%i set "mydrive=%%i\"
echo %mydrive%
Alternatively, without needing to use variables, you can use the already assigned metavariable %%i to use the drive letter as you please:
#for %%i in (m: p:) do #if exist %%i (
echo my drive letter is %%i
dir %%i
cd /d %%i
)

One approach you could utilise is to create a temporary mapping using pushD.
pushd \\Server\Share\path
When you are done with that temporary mapping just use popd to destroy it.
Where \Server\Share\path is the network resource to which you want to map a drive letter.
As soon as you use it, the PushD command will instantly map a drive letter to the network resource and then change to that drive right in the Command Prompt window.
Keep in mind that the PushD command allocates drive letters from Z: on down and will use the first unused drive letter that it finds.

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 file : overwrite one file to several existing files

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.

Changing the path location of a file to the desired path

I want to replace the content paths defined into the file i.e logging.properties to the desired location path of the jboss7 location .
Basically i'm using installer where i have to browse my jboss7 folder and locate it to any desired location of the user . But in few files of jboss7 there are some hardcoded path defined like in given logging.properties file.
I need to change that hard coded path to the desired location path.
As of now i'm having repl.bat and file test.bat files in the same folder.
repl.bat helper file could be find in following link:-
http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
I just copied the code and created repl.bat file.
test.bat file :-
#ECHO OFF
SETLOCAL
SET "folder="
FOR /r "C:\" %%a IN (tintin.txt) do IF EXIST "%%a" SET "folder=%%~dpa"&GOTO got1
FOR /r "D:\" %%a IN (tintin.txt) do IF EXIST "%%a" SET "folder=%%~dpa"&GOTO got1
:got1
echo "%folder%"
PAUSE
set "newpath=%folder%"
set "newpath=%newpath:\=\\%"
echo "%newpath%"
PAUSE
type "logging.properties" | repl "(Directory=).*(\\\\standalone\\\\)" "$1%newpath%$2">"logging.properties.tmp"
PAUSE
move "logging.properties.tmp" "logging.properties"
PAUSE
GOTO :EOF
PAUSE
Here in this test.bat file , i'm searching a file tintin.txt file and setting the path into a variable name as 'folder'. tintin.txt file is just inside the folder of jboss7.This is because of the possibilities of more than one jboss7 application server folder into the system.
Till now i have got the path i.e "C:\Users\Anuj\Desktop\jboss7\" and set into the variable 'folder'.
Now there is file named logging.properties into the folder location
C:\Users\Anuj\Desktop\jboss7\standalone\configuration
logging.properties :-
com.latilla.import.uploadDirectory=C:\\progra~2\\Latilla\\C4i\\jboss7\\ standalone\\uploads
com.latilla.import.maxFilesUploadNumber=10
com.latilla.export.templateFile=C:\\progra~2\\Latilla\\C4i\\jboss7\\standalone\\templates\\GDV_HDI_Format.xls
com.latilla.etl.pluginsRootDirectory=C:\\progra~2\\Latilla\\C4i\\jboss7\\standalone\\cloverETL\\plugins
com.latilla.etl.templatesDirectory=C:\\progra~2\\Latilla\\C4i\\jboss7\\standalone\\etl
com.latilla.db.user=postgres
com.latilla.db.pass=password
repl.bat helper file helps to replace the url path with the desired path i.e path set to variable name 'folder'.
I want to replace the C:\progra~2\Latilla\C4i\jboss7\ with the path set to variable name 'folder'.
Note :-
here in logging.properties file path contents is having different format of path i.e C:\
means double slash. \
Might be the script that i have tried test.bat is incorrect.
When i double click the test.bat file i got error.
Although I can't help you with fixing the issue you are getting while using the repl.bat file, I can suggest a different way of solving the initial problem of path replacement.
If the jboss7 string is guaranteed to be present in all the original paths in your configuration file(s), you could try the following approach:
#ECHO OFF
SETLOCAL DisableDelayedExpansion
FOR /F "delims=" %%A IN ('DIR /B /S C:\tintin.txt') DO (CD /D "%%~dpA" & CALL :got1)
FOR /F "delims=" %%A IN ('DIR /B /S D:\tintin.txt') DO (CD /D "%%~dpA" & CALL :got1)
GOTO :EOF
:got1
SET "propfile=%CD%\standalone\configuration\logging.properties"
IF NOT EXIST "%propfile%" GOTO :EOF
SET "tempfile=%TEMP%\logging.properties.tmp"
FIND /I /V "jboss7\\" >"%tempfile%"
>>"%tempfile%" (
FOR /F "tokens=1,* delims=" %%I IN ('FIND /I "jboss7\\"') DO (
SET "pathname=%%J"
SETLOCAL EnableDelayedExpansion
IF NOT "!pathname!" == "!pathname:*jboss7\\=!" (
SET "pathname=%__CD__:\=\\%!pathname:*jboss7\\=!"
)
ECHO %%I=!pathname!
ENDLOCAL
)
)
ECHO Old file "%propfile%":
TYPE "%propfile%"
ECHO =======================================
ECHO New file:
TYPE "%tempfile%"
PAUSE
:: uncomment the next line once you have verified the replacement works correctly
::MOVE "%tempfile%" "%propfile%"
Searching for the tintin.txt file has been changed slightly so as to possibly make the process faster. Instead of iterating over every directory and checking if it contains the file, the loops now read the output of DIR, which returns only actually existing entries.
Note that you could also use a FOR /R loop, as in your present code, with the same effect i.e. returning only existing paths, but the IN clause would need to contain a mask rather than a normal name, but that would have to be a mask that couldn't match anything else in your system than just tintin.txt. For instance, if you knew for certain that there could be no file called tintin.txt1 or tintin.txtx or anything else where tintin.txt is followed by exactly one character, you could use the following template instead:
FOR /R "C:\" %%A IN (tintin.txt?) DO (CD /D "%%~dpA" & CALL :got1)
and same for D:\. That would return only references to files actually existing and matching the mask.
Also, you can see that the loops do not jump (GOTO) to the got1 label but instead call the got1 subroutine. With that change, it is possible to process many application instances in one go. I don't know yours can be installed multiple times. If not, you'll probably want to change it back to GOTO.
The subroutine in my script is referencing the config file using its full path as specified in your description (...\standalone\configuration\logging.properties). For some reason, in your script the file is referenced simply by its name, even though there's no preceding CD or PUSHD command changing the current directory to the location of the file. I assumed you were trying to simplify your script and omitted that bit, whether intentionally or not. Otherwise I may have missed something in your explanation and/or script.
After verifying that the config file exists at the expected location, the replacement itself is done in this way:
All the non-path config lines are written to a temporary file with one go.
Every config line containing a path is processed in this way:
if it does not contain the jboss7\\ string, it is omitted;
otherwise the part of the path up to and including jboss7\\ is removed;
the current directory is inserted before the remaining part (after every \ is replaced with \\);
the new value is put back into the config line;
the update line is added to the same temporary file.
The old version is of the configuration file replaced with the new one.
Obviously, the script may change the order of lines in the processed file, but it is assumed that that doesn't matter.

How to remove all folders of name x within a directory using cmd/batch file

I have a folder named x with a number of subfolders and files. I want to delete a folder named y that is present in x and all of it's subfolders. The said folder that has to be deleted may or may not contain any files. I believe i can do this using cmd or some kind of batch file but i am a command line new bi and can really use some help.
A simple thing would be to rd the folder's name, which works but i believe there are better ways than removing each folder individually.. like some loop that goes through all the folders.
Thanks
EDIT: Just to clarify, i have y (the folder that needs to be deleted) inside of x, and it can be in any of x's subfolders and at any level of depth. Also i am looking at answers and it may take some time for me to accept any answer. Please bear with me :)
Here is another solution for this commented to describe each part of the script:
#Echo OFF
REM Important that Delayed Expansion is Enabled
setlocal enabledelayedexpansion
REM This sets what folder the batch is looking for and the root in which it starts the search:
set /p foldername=Please enter the foldername you want to delete:
set /p root=Please enter the root directory (ex: C:\TestFolder)
REM Checks each directory in the given root
FOR /R %root% %%A IN (.) DO (
if '%%A'=='' goto end
REM Correctly parses info for executing the loop and RM functions
set dir="%%A"
set dir=!dir:.=!
set directory=%%A
set directory=!directory::=!
set directory=!directory:\=;!
REM Checks each directory
for /f "tokens=* delims=;" %%P in ("!directory!") do call :loop %%P
)
REM After each directory is checked the batch will allow you to see folders deleted.
:end
pause
endlocal
exit
REM This loop checks each folder inside the directory for the specified folder name. This allows you to check multiple nested directories.
:loop
if '%1'=='' goto endloop
if '%1'=='%foldername%' (
rd /S /Q !dir!
echo !dir! was deleted.
)
SHIFT
goto :loop
:endloop
You can take the /p out from in front of the initial variables and just enter their values after the = if you don't want to be prompted:
set foldername=
set root=
You can also remove the echo in the loop portion and the pause in the end portion for the batch to run silently.
It might be a little more complicated, but the code can be applied to a lot of other uses.
I tested it looking for multiple instances of the same foldername qwerty in C:\Test:
C:\Test\qwerty
C:\Test\qwerty\subfolder
C:\Test\test\qwerty
C:\Test\test\test\qwerty
and all that was left was:
C:\Test\
C:\Test\test\
C:\Test\test\test\
FOR /D /R %%X IN (fileprefix*) DO RD /S /Q "%%X"
Take care of using that...
for RD command:
/S Removes all directories and files in the specified directory
in addition to the directory itself. Used to remove a directory
tree.
/Q Quiet mode, do not ask if ok to remove a directory tree with /S
the FOR command is used to loop through a list of files or variables, the options are very easy to memorize, Directory only Recursively.
A problem common to this type of topics is that if there are instances of the target folder at several levels, most methods cause an error because when an high level folder is deleted, all folders below it disappear. For example:
C:\X\Y\subfolder
C:\X\Y\subfolder\one\Y
C:\X\Y\subfolder\two\Y
C:\X\Y\subfolder\three\Y
C:\X\test
C:\X\test\test
Previous example generate a list of 4 folders named Y that will be deleted, but after the first one is deleted the three remaining names no longer exist, causing an error message when they are tried to delete. I understand this is a possibility in your case.
To solve this problem the folders must be deleted in bottom-up order, that is, the innermost folder must be deleted first and the top level folder must be deleted last. The way to achieve this is via a recursive subroutine:
#echo off
rem Enter into top level folder, process it and go back to original folder
pushd x
call :processFolder
popd
goto :EOF
:processFolder
rem For each folder in this level
for /D %%a in (*) do (
rem Enter into it, process it and go back to original
cd %%a
call :processFolder
cd ..
rem If is the target folder, delete it
if /I "%%a" == "y" (
rd /S /Q "%%a"
)
)
exit /B
Although in this particular case the problems caused by other methods are just multiple error messages, there are other cases when this processing order is fundamental.
Make .bat with following:
del /q "C:\Users\XXX\AppData\Local\Temp\*"
FOR /D %%p IN ("C:\Users\XXX\AppData\Local\Temp\*.*") DO rmdir "%%p" /s /q

Resources